<!DOCTYPE html>

<html lang="en">
  <head>
    
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>使用模型（Working with Models） &mdash; Phalcon 3.0.1 文档</title>
    <meta name="keywords" content="php, phalcon, phalcon php, php framework, faster php framework">
    <link rel="stylesheet" type="text/css" href="http://cdn.staticfile.org/twitter-bootstrap/3.3.6/css/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="/www/css/phalcon.min.css" />
    <link href='//fonts.googleapis.com/css?family=Open+Sans:700,400' rel='stylesheet' type='text/css'>
    <link href="//fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css" />
    <!--
    EUROPE <link href='//fonts.googleapis.com/css?family=Open+Sans:700,400&subset=latin-ext' rel='stylesheet' type='text/css'>
    GREEK <link href='//fonts.googleapis.com/css?family=Open+Sans:700,400&subset=greek-ext' rel='stylesheet' type='text/css'>
    RUSSIA <link href='//fonts.googleapis.com/css?family=Open+Sans:700,400&subset=cyrillic-ext,latin' rel='stylesheet' type='text/css'>
    -->

    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
      <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

    <link rel="stylesheet" href="../static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="../static/docs.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../',
        VERSION:     '3.0.1',
        COLLAPSE_MODINDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>

    <script src="http://cdn.staticfile.org/jquery/1.8.1/jquery.min.js"></script>
    <script type="text/javascript" src="../static/docs.js"></script>
    <link rel="shortcut icon" href="../static/favicon.ico"/>
    <link rel="top" title="Phalcon 3.0.1 文档" href="../index.html" />
    <link rel="next" title="Model Behaviors" href="model-behaviors.html" />
    <link rel="prev" title="使用控制器（Using Controllers）" href="controllers.html" /> 
  </head>
  <body>

<header class="page-header">
    <nav class="navbar" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#main-menu-container">
                    <span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>
                </button>
                <a class="navbar-brand phalcon-logo" href="/"><span itemprop="name" class="sr-only">Phalcon PHP</span></a>
            </div>

            <div class="collapse navbar-collapse navbar-right" id="main-menu-container">
                <ul class="nav navbar-nav main-menu">
                  <li class="first"><a href="//phalconphp.com/en/download" class="header-nav-link">Download</a></li>
                  <li><a href="//docs.phalconphp.com/en/latest/index.html" class="header-nav-link" target="_blank">Documentation</a></li>
                  <li><a href="//forum.phalconphp.com/" class="header-nav-link" target="_blank">Forum</a></li>
                  <li><a href="//blog.phalconphp.com/" class="header-nav-link" target="_blank">Blog</a></li>
                  <li><a href="//phalconist.com/" class="header-nav-link" target="_blank">Resources</a></li>
                  <li><a href="//phalconphp.com/en/about">About</a></li>
                  <li><div align="right">
                      <iframe src="https://ghbtns.com/github-btn.html?user=phalcon&amp;repo=cphalcon&amp;type=watch&amp;count=true&amp;size=large"
      allowtransparency="true" frameborder="0" scrolling="0" width="152px" height="30px"></iframe>
                    </div></li>
                </ul>
            </div>
        </div>
    </nav>
  </header>

<div class="heading">
    <div class="container">
        <div class="row">
            <h2>Documentation</h2>
        </div>
    </div>
</div>
    <div class="related">
      <ul>
        <li class="right" >
          <a href="../genindex.html" title="总目录"
             accesskey="I">索引</a></li>
        <li class="right" >
          <a href="model-behaviors.html" title="Model Behaviors"
             accesskey="N">下一页</a> |</li>
        <li class="right" >
          <a href="controllers.html" title="使用控制器（Using Controllers）"
             accesskey="P">上一页</a> |</li>
        <li><a href="//phalconphp.com">Home</a> &raquo;</li>
        <li><a href="../index.html">Phalcon 3.0.1 文档</a> &raquo;</li> 
      </ul>
    </div>  

      <table width="100%" align="center" cellpadding="0" cellspacing="0">
        <tr>
      <td class="primary-box" width="25%" valign="top">
            <div>
            <div id="searchbox" style="">
                <!--<form class="search" action="http://readthedocs.org/search/project/" method="get">
                  <input type="search" name="q" size="25" placeholder="Search">
                  <input type="submit" value="Go">
                  <input type="hidden" name="selected_facets" value="project:">
                </form>-->
                <div style="width:200px;padding:10px">
                  <gcse:searchbox-only></gcse:searchbox-only>
                </div>
            </div>
            </div>
            <div style="padding:5px;padding-left:10px">
              <div id="carbonads-container">
                <div class="carbonad"><div id="azcarbon"></div>
                <script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?zoneid=1673&serve=C6AILKT&placement=phalconphpcom" id="_carbonads_js"></script>
                </div></div>
            </div>
            <h3><a href="../index.html">內容目录</a></h3>
            <ul>
<li><a class="reference internal" href="#">使用模型（Working with Models）</a><ul>
<li><a class="reference internal" href="#id1">创建模型</a><ul>
<li><a class="reference internal" href="#setters-getters-public-properties-vs-setters-getters">公共属性对比设置与取值 Setters/Getters（Public properties vs. Setters/Getters）</a></li>
</ul>
</li>
<li><a class="reference internal" href="#understanding-records-to-objects">理解记录对象（Understanding Records To Objects）</a></li>
<li><a class="reference internal" href="#finding-records">查找记录（Finding Records）</a><ul>
<li><a class="reference internal" href="#model-resultsets">模型结果集（Model Resultsets）</a></li>
<li><a class="reference internal" href="#filtering-resultsets">过滤结果集（Filtering Resultsets）</a></li>
<li><a class="reference internal" href="#binding-parameters">绑定参数（Binding Parameters）</a></li>
</ul>
</li>
<li><a class="reference internal" href="#initializing-preparing-fetched-records">获取记录的初始化以及准备（Initializing/Preparing fetched records）</a></li>
<li><a class="reference internal" href="#relationships-between-models">模型关系（Relationships between Models）</a><ul>
<li><a class="reference internal" href="#unidirectional-relationships">单向关系（Unidirectional relationships）</a></li>
<li><a class="reference internal" href="#bidirectional-relations">双向关系（Bidirectional relations）</a></li>
<li><a class="reference internal" href="#defining-relationships">定义关系（Defining relationships）</a></li>
<li><a class="reference internal" href="#taking-advantage-of-relationships">使用关系（Taking advantage of relationships）</a></li>
<li><a class="reference internal" href="#aliasing-relationships">定义关系（Aliasing Relationships）</a></li>
<li><a class="reference internal" href="#getters-magic-getters-vs-explicit-methods">魔术方法 Getters 对比显示方法（Magic Getters vs. Explicit methods）</a></li>
</ul>
</li>
<li><a class="reference internal" href="#virtual-foreign-keys">虚拟外键（Virtual Foreign Keys）</a><ul>
<li><a class="reference internal" href="#cascade-restrict-actions">级联与限制动作（Cascade/Restrict actions）</a></li>
</ul>
</li>
<li><a class="reference internal" href="#generating-calculations">生成运算（Generating Calculations）</a></li>
<li><a class="reference internal" href="#hydration-modes">Hydration Modes</a></li>
<li><a class="reference internal" href="#creating-updating-records">创建与更新记录（Creating/Updating Records）</a><ul>
<li><a class="reference internal" href="#create-update-with-confidence">创建与更新结果判断（Create/Update with Confidence）</a></li>
<li><a class="reference internal" href="#auto-generated-identity-columns">自动生成标识列（Auto-generated identity columns）</a></li>
<li><a class="reference internal" href="#storing-related-records">存储关系记录（Storing related records）</a></li>
<li><a class="reference internal" href="#validation-messages">验证信息（Validation Messages）</a></li>
<li><a class="reference internal" href="#events-and-events-manager">事件与事件管理器（Events and Events Manager）</a></li>
<li><a class="reference internal" href="#implementing-events-in-the-model-s-class">模型中自定义事件（Implementing Events in the Model&#8217;s class）</a></li>
<li><a class="reference internal" href="#using-a-custom-events-manager">使用自定义事件管理器（Using a custom Events Manager）</a></li>
<li><a class="reference internal" href="#implementing-a-business-rule">实现业务逻辑（Implementing a Business Rule）</a></li>
<li><a class="reference internal" href="#validating-data-integrity">验证数据完整性（Validating Data Integrity）</a></li>
</ul>
</li>
<li><a class="reference internal" href="#skipping-columns">忽略指定列的数据（Skipping Columns）</a><ul>
<li><a class="reference internal" href="#dynamic-update">动态更新（Dynamic Update）</a></li>
</ul>
</li>
<li><a class="reference internal" href="#deleting-records">删除记录（Deleting Records）</a></li>
<li><a class="reference internal" href="#validation-failed-events">验证失败事件（Validation Failed Events）</a></li>
<li><a class="reference internal" href="#independent-column-mapping">独立的列映射（Independent Column Mapping）</a></li>
<li><a class="reference internal" href="#operations-over-resultsets">在结果集中操作（Operations over Resultsets）</a><ul>
<li><a class="reference internal" href="#updating-related-records">更新关联表记录（Updating related records）</a></li>
<li><a class="reference internal" href="#deleting-related-records">删除关联表记录（Deleting related records）</a></li>
</ul>
</li>
<li><a class="reference internal" href="#record-snapshots">记录快照（Record Snapshots）</a></li>
<li><a class="reference internal" href="#pointing-to-a-different-schema">设置模式（Pointing to a different schema）</a></li>
<li><a class="reference internal" href="#setting-multiple-databases">设置多个数据库（Setting multiple databases）</a></li>
<li><a class="reference internal" href="#sql-logging-low-level-sql-statements">记录底层 SQL 语句（Logging Low-Level SQL Statements）</a></li>
<li><a class="reference internal" href="#sql-profiling-sql-statements">分析 SQL 语句（Profiling SQL Statements）</a></li>
<li><a class="reference internal" href="#injecting-services-into-models">注入服务到模型（Injecting services into Models）</a></li>
<li><a class="reference internal" href="#disabling-enabling-features">禁用或启用特性（Disabling/Enabling Features）</a></li>
<li><a class="reference internal" href="#stand-alone-component">独立的组件（Stand-Alone component）</a></li>
</ul>
</li>
</ul>

            <h4>上一个主题</h4>
            <p class="topless"><a href="controllers.html" title="上一章">&lt; 使用控制器（Using Controllers）</a></p>
            <h4>下一个主题</h4>
            <p class="topless"><a href="model-behaviors.html" title="下一章">Model Behaviors &gt;</a></p>
            <h3>本页</h3>
            <ul class="this-page-menu">
              <li><a href="../sources/reference/models.md" rel="nofollow">显示源代码</a></li>
            </ul>
        </td>
          <td class="second-box" valign="top">
            <div class="document">
                <div class="documentwrapper">
                  <div class="bodywrapper">
                    <div class="body" >
                      
  <div class="section" id="working-with-models">
<h1>使用模型（Working with Models）<a class="headerlink" href="#working-with-models" title="永久链接至标题">¶</a></h1>
<p>模型代表了应用程序中的信息（数据）和处理数据的规则。模型主要用于管理与相应数据库表进行交互的规则。
大多数情况中，在应用程序中，数据库中每个表将对应一个模型。
应用程序中的大部分业务逻辑都将集中在模型里。</p>
<p><a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> 是 Phalcon 应用程序中所有模型的基类。它保证了数据库的独立性，基本的 CURD 操作，
高级的查询功能，多表关联等功能。
<a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> 不需要直接使用 SQL 语句，因为它的转换方法，会动态的调用相应的数据库引擎进行处理。</p>
<blockquote class="highlights">
<div>模型是数据库的高级抽象层。如果您想进行低层次的数据库操作，您可以查看
<a class="reference internal" href="../api/Phalcon_Db.html"><em>Phalcon\Db</em></a> 组件文档。</div></blockquote>
<div class="section" id="id1">
<h2>创建模型<a class="headerlink" href="#id1" title="永久链接至标题">¶</a></h2>
<p>模型是一个继承自 <a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> 的一个类。时它的类名必须符合驼峰命名法：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>

<span class="p">}</span>
</pre></div>
</div>
<blockquote class="highlights">
<div>如果使用 PHP 5.4/5.5 建议在模型中预先定义好所有的列，这样可以减少模型内存的开销以及内存分配。</div></blockquote>
<p>默认情况下，模型 &#8220;Store\Toys\Robots&#8221; 对应的是数据库表 &#8220;robots&#8221;， 如果想映射到其他数据库表，可以使用 <code class="code docutils literal"><span class="pre">setSource()</span></code> 方法：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setSource</span><span class="p">(</span><span class="s2">&quot;toys_robots&quot;</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>模型 Robots 现在映射到了 &#8220;toys_robots&#8221; 表。<code class="code docutils literal"><span class="pre">initialize()</span></code> 方法可以帮助在模型中建立自定义行为，例如指定不同的数据库表。</p>
<p><code class="code docutils literal"><span class="pre">initialize()</span></code> 方法在请求期间仅会被调用一次，目的是为应用中所有该模型的实例进行初始化。如果需要为每一个实例在创建的时候单独进行初始化，
可以使用 <code class="code docutils literal"><span class="pre">onConstruct()</span></code> 事件：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">onConstruct</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="c1">// ...</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="section" id="setters-getters-public-properties-vs-setters-getters">
<h3>公共属性对比设置与取值 Setters/Getters（Public properties vs. Setters/Getters）<a class="headerlink" href="#setters-getters-public-properties-vs-setters-getters" title="永久链接至标题">¶</a></h3>
<p>模型可以通过公共属性的方式实现，意味着模型的所有属性在实例化该模型的地方可以无限制的读取和更新。</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$name</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$price</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>通过使用 getters/setters 方法，可以控制哪些属性可以公开访问，并且对属性值执行不同的形式的转换，同时可以保存在模型中的数据添加相应的验证规则。</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">InvalidArgumentException</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">protected</span> <span class="nv">$id</span><span class="p">;</span>

    <span class="k">protected</span> <span class="nv">$name</span><span class="p">;</span>

    <span class="k">protected</span> <span class="nv">$price</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">getId</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">id</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">setName</span><span class="p">(</span><span class="nv">$name</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// The name is too short?</span>
        <span class="k">if</span> <span class="p">(</span><span class="nb">strlen</span><span class="p">(</span><span class="nv">$name</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nx">InvalidArgumentException</span><span class="p">(</span>
                <span class="s2">&quot;The name is too short&quot;</span>
            <span class="p">);</span>
        <span class="p">}</span>

        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">getName</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">setPrice</span><span class="p">(</span><span class="nv">$price</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// Negative prices aren&#39;t allowed</span>
        <span class="k">if</span> <span class="p">(</span><span class="nv">$price</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nx">InvalidArgumentException</span><span class="p">(</span>
                <span class="s2">&quot;Price can&#39;t be negative&quot;</span>
            <span class="p">);</span>
        <span class="p">}</span>

        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">price</span> <span class="o">=</span> <span class="nv">$price</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">getPrice</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="c1">// Convert the value to double before be used</span>
        <span class="k">return</span> <span class="p">(</span><span class="nx">double</span><span class="p">)</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">price</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>公共属性的方式可以在开发中降低复杂度。而 getters/setters 的实现方式可以显著的增强应用的可测试性、扩展性和可维护性。
开发人员可以自己决定哪一种策略更加适合自己开发的应用。ORM同时兼容这两种方法。</p>
<blockquote class="highlights">
<div>Underscores in property names can be problematic when using getters and setters.</div></blockquote>
<p>If you use underscores in your property names, you must still use camel case in your getter/setter declarations for use
with magic methods. (e.g. $model-&gt;getPropertyName instead of $model-&gt;getProperty_name, $model-&gt;findByPropertyName
instead of $model-&gt;findByProperty_name, etc.). As much of the system expects camel case, and underscores are commonly
removed, it is recommended to name your properties in the manner shown throughout the documentation. You can use a
column map (as described above) to ensure proper mapping of your properties to their database counterparts.</p>
</div>
</div>
<div class="section" id="understanding-records-to-objects">
<h2>理解记录对象（Understanding Records To Objects）<a class="headerlink" href="#understanding-records-to-objects" title="永久链接至标题">¶</a></h2>
<p>每个模型的实例对应一条数据表中的记录。可以方便的通过读取对象的属性来访问相应的数据。比如，
一个表 &#8220;robots&#8221; 有如下数据：</p>
<div class="highlight-bash"><div class="highlight"><pre>mysql&gt; <span class="k">select</span> * from robots<span class="p">;</span>
+----+------------+------------+------+
<span class="p">|</span> id <span class="p">|</span> name       <span class="p">|</span> <span class="nb">type</span>       <span class="p">|</span> year <span class="p">|</span>
+----+------------+------------+------+
<span class="p">|</span>  <span class="m">1</span> <span class="p">|</span> Robotina   <span class="p">|</span> mechanical <span class="p">|</span> <span class="m">1972</span> <span class="p">|</span>
<span class="p">|</span>  <span class="m">2</span> <span class="p">|</span> Astro Boy  <span class="p">|</span> mechanical <span class="p">|</span> <span class="m">1952</span> <span class="p">|</span>
<span class="p">|</span>  <span class="m">3</span> <span class="p">|</span> Terminator <span class="p">|</span> cyborg     <span class="p">|</span> <span class="m">2029</span> <span class="p">|</span>
+----+------------+------------+------+
<span class="m">3</span> rows in <span class="nb">set</span> <span class="o">(</span>0.00 sec<span class="o">)</span>
</pre></div>
</div>
<p>你可以通过主键找到某一条记录并且打印它的名称：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="c1">// Find record with id = 3</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>

<span class="c1">// Prints &quot;Terminator&quot;</span>
<span class="k">echo</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">;</span>
</pre></div>
</div>
<p>一旦记录被加载到内存中之后，你可以修改它的数据并保存所做的修改：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="s2">&quot;RoboCop&quot;</span><span class="p">;</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">save</span><span class="p">();</span>
</pre></div>
</div>
<p>如上所示，不需要写任何SQL语句。<a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> 为web应用提供了高层数据库抽象。</p>
</div>
<div class="section" id="finding-records">
<h2>查找记录（Finding Records）<a class="headerlink" href="#finding-records" title="永久链接至标题">¶</a></h2>
<p><a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> 为数据查询提供了多种方法。下面的例子将演示如何从一个模型中查找一条或者多条记录：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="c1">// How many robots are there?</span>
<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">();</span>
<span class="k">echo</span> <span class="s2">&quot;There are &quot;</span><span class="p">,</span> <span class="nb">count</span><span class="p">(</span><span class="nv">$robots</span><span class="p">),</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>

<span class="c1">// How many mechanical robots are there?</span>
<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span><span class="s2">&quot;type = &#39;mechanical&#39;&quot;</span><span class="p">);</span>
<span class="k">echo</span> <span class="s2">&quot;There are &quot;</span><span class="p">,</span> <span class="nb">count</span><span class="p">(</span><span class="nv">$robots</span><span class="p">),</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>

<span class="c1">// Get and print virtual robots ordered by name</span>
<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;type = &#39;virtual&#39;&quot;</span><span class="p">,</span>
        <span class="s2">&quot;order&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;name&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$robots</span> <span class="k">as</span> <span class="nv">$robot</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// Get first 100 virtual robots ordered by name</span>
<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;type = &#39;virtual&#39;&quot;</span><span class="p">,</span>
        <span class="s2">&quot;order&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;name&quot;</span><span class="p">,</span>
        <span class="s2">&quot;limit&quot;</span> <span class="o">=&gt;</span> <span class="mi">100</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$robots</span> <span class="k">as</span> <span class="nv">$robot</span><span class="p">)</span> <span class="p">{</span>
   <span class="k">echo</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<blockquote class="highlights">
<div>如果需要通过外部数据（比如用户输入）或变量来查询记录，则必须要用`Binding Parameters`（绑定参数）的方式来防止SQL注入.</div></blockquote>
<p>你可以使用 <code class="code docutils literal"><span class="pre">findFirst()</span></code> 方法获取第一条符合查询条件的结果：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="c1">// What&#39;s the first robot in robots table?</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">();</span>
<span class="k">echo</span> <span class="s2">&quot;The robot name is &quot;</span><span class="p">,</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>

<span class="c1">// What&#39;s the first mechanical robot in robots table?</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span><span class="s2">&quot;type = &#39;mechanical&#39;&quot;</span><span class="p">);</span>
<span class="k">echo</span> <span class="s2">&quot;The first mechanical robot name is &quot;</span><span class="p">,</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>

<span class="c1">// Get first virtual robot ordered by name</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;type = &#39;virtual&#39;&quot;</span><span class="p">,</span>
        <span class="s2">&quot;order&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;name&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>
<span class="k">echo</span> <span class="s2">&quot;The first virtual robot name is &quot;</span><span class="p">,</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
</pre></div>
</div>
<p><code class="code docutils literal"><span class="pre">find()</span></code> 和 <code class="code docutils literal"><span class="pre">findFirst()</span></code> 方法都接受关联数组作为查询条件：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;type = &#39;virtual&#39;&quot;</span><span class="p">,</span>
        <span class="s2">&quot;order&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;name DESC&quot;</span><span class="p">,</span>
        <span class="s2">&quot;limit&quot;</span> <span class="o">=&gt;</span> <span class="mi">30</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;conditions&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;type = ?1&quot;</span><span class="p">,</span>
        <span class="s2">&quot;bind&quot;</span>       <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="mi">1</span> <span class="o">=&gt;</span> <span class="s2">&quot;virtual&quot;</span><span class="p">,</span>
        <span class="p">]</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<p>可用的查询选项如下：</p>
<p>如果你愿意，除了使用数组作为查询参数外，还可以通过一种面向对象的方式来创建查询：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">query</span><span class="p">()</span>
    <span class="o">-&gt;</span><span class="na">where</span><span class="p">(</span><span class="s2">&quot;type = :type:&quot;</span><span class="p">)</span>
    <span class="o">-&gt;</span><span class="na">andWhere</span><span class="p">(</span><span class="s2">&quot;year &lt; 2000&quot;</span><span class="p">)</span>
    <span class="o">-&gt;</span><span class="na">bind</span><span class="p">([</span><span class="s2">&quot;type&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;mechanical&quot;</span><span class="p">])</span>
    <span class="o">-&gt;</span><span class="na">order</span><span class="p">(</span><span class="s2">&quot;name&quot;</span><span class="p">)</span>
    <span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
<p>静态方法 <code class="code docutils literal"><span class="pre">query()</span></code> 返回一个对IDE自动完成友好的 <a class="reference internal" href="../api/Phalcon_Mvc_Model_Criteria.html"><em>Phalcon\Mvc\Model\Criteria</em></a>  对象。</p>
<p>所有查询在内部都以 <a class="reference internal" href="phql.html"><em>PHQL</em></a> 查询的方式处理。PHQL是一个高层的、面向对象的类SQL语言。通过PHQL语言你可以使用更多的比如join其他模型、定义分组、添加聚集等特性。</p>
<p>最后，还有一个 <code class="code docutils literal"><span class="pre">findFirstBy&lt;property-name&gt;()</span></code> 方法。这个方法扩展了前面提及的 <code class="code docutils literal"><span class="pre">findFirst()</span></code> 方法。它允许您利用方法名中的属性名称，通过将要搜索的该字段的内容作为参数传给它，来快速从一个表执行检索操作。</p>
<p>还是用上面用过的 Robots 模型来举例说明：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$name</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$price</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>我们这里有3个属性：<code class="code docutils literal"><span class="pre">$id</span></code>, <code class="code docutils literal"><span class="pre">$name</span></code> 和 <code class="code docutils literal"><span class="pre">$price</span></code>。因此，我们以想要查询第一个名称为 &#8216;Terminator&#8217; 的记录为例，可以这样写：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$name</span> <span class="o">=</span> <span class="s2">&quot;Terminator&quot;</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirstByName</span><span class="p">(</span><span class="nv">$name</span><span class="p">);</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$robot</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s2">&quot;The first robot with the name &quot;</span> <span class="o">.</span> <span class="nv">$name</span> <span class="o">.</span> <span class="s2">&quot; cost &quot;</span> <span class="o">.</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">price</span> <span class="o">.</span> <span class="s2">&quot;.&quot;</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s2">&quot;There were no robots found in our table with the name &quot;</span> <span class="o">.</span> <span class="nv">$name</span> <span class="o">.</span> <span class="s2">&quot;.&quot;</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>请注意我们在方法调用中用的是 &#8216;Name&#8217;，并向它传递了变量 <code class="code docutils literal"><span class="pre">$name</span></code>， <code class="code docutils literal"><span class="pre">$name</span></code> 的值就是我们想要找的记录的名称。另外注意，当我们的查询找到了符合的记录后，这个记录的其他属性也都是可用的。</p>
<div class="section" id="model-resultsets">
<h3>模型结果集（Model Resultsets）<a class="headerlink" href="#model-resultsets" title="永久链接至标题">¶</a></h3>
<p><code class="code docutils literal"><span class="pre">findFirst()</span></code> 方法直接返回一个被调用对象的实例（如果有结果返回的话），而 <code class="code docutils literal"><span class="pre">find()</span></code> 方法返回一个 <a class="reference internal" href="../api/Phalcon_Mvc_Model_Resultset_Simple.html"><em>Phalcon\Mvc\Model\Resultset\Simple</em></a> 对象。这个对象也封装进了所有结果集的功能，比如遍历、查找特定的记录、统计等等。</p>
<p>这些对象比一般数组功能更强大。最大的特点是 <a class="reference internal" href="../api/Phalcon_Mvc_Model_Resultset.html"><em>Phalcon\Mvc\Model\Resultset</em></a> 每时每刻只有一个结果在内存中。这对操作大数据量时的内存管理相当有帮助。</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="c1">// Get all robots</span>
<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">();</span>

<span class="c1">// Traversing with a foreach</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$robots</span> <span class="k">as</span> <span class="nv">$robot</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// Traversing with a while</span>
<span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">rewind</span><span class="p">();</span>

<span class="k">while</span> <span class="p">(</span><span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">valid</span><span class="p">())</span> <span class="p">{</span>
    <span class="nv">$robot</span> <span class="o">=</span> <span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">current</span><span class="p">();</span>

    <span class="k">echo</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>

    <span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">next</span><span class="p">();</span>
<span class="p">}</span>

<span class="c1">// Count the resultset</span>
<span class="k">echo</span> <span class="nb">count</span><span class="p">(</span><span class="nv">$robots</span><span class="p">);</span>

<span class="c1">// Alternative way to count the resultset</span>
<span class="k">echo</span> <span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">count</span><span class="p">();</span>

<span class="c1">// Move the internal cursor to the third robot</span>
<span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">seek</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">current</span><span class="p">();</span>

<span class="c1">// Access a robot by its position in the resultset</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nv">$robots</span><span class="p">[</span><span class="mi">5</span><span class="p">];</span>

<span class="c1">// Check if there is a record in certain position</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">isset</span><span class="p">(</span><span class="nv">$robots</span><span class="p">[</span><span class="mi">3</span><span class="p">]))</span> <span class="p">{</span>
   <span class="nv">$robot</span> <span class="o">=</span> <span class="nv">$robots</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>
<span class="p">}</span>

<span class="c1">// Get the first record in the resultset</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">getFirst</span><span class="p">();</span>

<span class="c1">// Get the last record</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">getLast</span><span class="p">();</span>
</pre></div>
</div>
<p>Phalcon 的结果集模拟了可滚动的游标，你可以通过位置，或者内部指针去访问任何一条特定的记录。注意有一些数据库系统不支持滚动游标，这就使得查询会被重复执行，
以便回放光标到最开始的位置，然后获得相应的记录。类似地，如果多次遍历结果集，那么必须执行相同的查询次数。</p>
<p>将大数据量的查询结果存储在内存会消耗很多资源，正因为如此，分成每32行一块从数据库中获得结果集，以减少重复执行查询请求的次数，在一些情况下也节省内存。</p>
<p>注意结果集可以序列化后保存在一个后端缓存里面。 <a class="reference internal" href="cache.html"><em>Phalcon\Cache</em></a> 可以用来实现这个。但是，序列化数据会导致 <a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a>
将从数据库检索到的所有数据以一个数组的方式保存，因此在这样执行的地方会消耗更多的内存。</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">// Query all records from model parts</span>
<span class="nv">$parts</span> <span class="o">=</span> <span class="nx">Parts</span><span class="o">::</span><span class="na">find</span><span class="p">();</span>

<span class="c1">// Store the resultset into a file</span>
<span class="nb">file_put_contents</span><span class="p">(</span>
    <span class="s2">&quot;cache.md&quot;</span><span class="p">,</span>
    <span class="nb">serialize</span><span class="p">(</span><span class="nv">$parts</span><span class="p">)</span>
<span class="p">);</span>

<span class="c1">// Get parts from file</span>
<span class="nv">$parts</span> <span class="o">=</span> <span class="nb">unserialize</span><span class="p">(</span>
    <span class="nb">file_get_contents</span><span class="p">(</span><span class="s2">&quot;cache.md&quot;</span><span class="p">)</span>
<span class="p">);</span>

<span class="c1">// Traverse the parts</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$parts</span> <span class="k">as</span> <span class="nv">$part</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="nv">$part</span><span class="o">-&gt;</span><span class="na">id</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="filtering-resultsets">
<h3>过滤结果集（Filtering Resultsets）<a class="headerlink" href="#filtering-resultsets" title="永久链接至标题">¶</a></h3>
<p>过滤数据最有效的方法是设置一些查询条件，数据库会利用表的索引快速返回数据。Phalcon 额外的允许你通过任何数据库不支持的方式过滤数据。</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$customers</span> <span class="o">=</span> <span class="nx">Customers</span><span class="o">::</span><span class="na">find</span><span class="p">();</span>

<span class="nv">$customers</span> <span class="o">=</span> <span class="nv">$customers</span><span class="o">-&gt;</span><span class="na">filter</span><span class="p">(</span>
    <span class="k">function</span> <span class="p">(</span><span class="nv">$customer</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// Return only customers with a valid e-mail</span>
        <span class="k">if</span> <span class="p">(</span><span class="nb">filter_var</span><span class="p">(</span><span class="nv">$customer</span><span class="o">-&gt;</span><span class="na">email</span><span class="p">,</span> <span class="nx">FILTER_VALIDATE_EMAIL</span><span class="p">))</span> <span class="p">{</span>
            <span class="k">return</span> <span class="nv">$customer</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="binding-parameters">
<h3>绑定参数（Binding Parameters）<a class="headerlink" href="#binding-parameters" title="永久链接至标题">¶</a></h3>
<p>在 <a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> 中也支持绑定参数。即使使用绑定参数对性能有一点很小的影响，还是强烈建议您使用这种方法，以消除代码受SQL注入攻击的可能性。
绑定参数支持字符串和整数占位符。实现方法如下：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="c1">// Query robots binding parameters with string placeholders</span>
<span class="c1">// Parameters whose keys are the same as placeholders</span>
<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;name = :name: AND type = :type:&quot;</span><span class="p">,</span>
        <span class="s2">&quot;bind&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="s2">&quot;name&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;Robotina&quot;</span><span class="p">,</span>
            <span class="s2">&quot;type&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;maid&quot;</span><span class="p">,</span>
        <span class="p">],</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="c1">// Query robots binding parameters with integer placeholders</span>
<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;name = ?1 AND type = ?2&quot;</span><span class="p">,</span>
        <span class="s2">&quot;bind&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="mi">1</span> <span class="o">=&gt;</span> <span class="s2">&quot;Robotina&quot;</span><span class="p">,</span>
            <span class="mi">2</span> <span class="o">=&gt;</span> <span class="s2">&quot;maid&quot;</span><span class="p">,</span>
        <span class="p">],</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="c1">// Query robots binding parameters with both string and integer placeholders</span>
<span class="c1">// Parameters whose keys are the same as placeholders</span>
<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;name = :name: AND type = ?1&quot;</span><span class="p">,</span>
        <span class="s2">&quot;bind&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="s2">&quot;name&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;Robotina&quot;</span><span class="p">,</span>
            <span class="mi">1</span>      <span class="o">=&gt;</span> <span class="s2">&quot;maid&quot;</span><span class="p">,</span>
        <span class="p">],</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<p>如果是数字占位符，则必须把它们定义成整型（如1或者2）。若是定义为字符串型（如&#8221;1&#8221;或者&#8221;2&#8221;），则这个占位符不会被替换。</p>
<p>使用PDO_的方式会自动转义字符串。它依赖于字符集编码，因此建议在连接参数或者数据库配置中设置正确的字符集编码。
若是设置错误的字符集编码，在存储数据或检索数据时，可能会出现乱码。</p>
<p>另外你可以设置参数的“bindTypes”，这允许你根据数据类型来定义参数应该如何绑定：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Db\Column</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="c1">// Bind parameters</span>
<span class="nv">$parameters</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s2">&quot;name&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;Robotina&quot;</span><span class="p">,</span>
    <span class="s2">&quot;year&quot;</span> <span class="o">=&gt;</span> <span class="mi">2008</span><span class="p">,</span>
<span class="p">];</span>

<span class="c1">// Casting Types</span>
<span class="nv">$types</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s2">&quot;name&quot;</span> <span class="o">=&gt;</span> <span class="nx">Column</span><span class="o">::</span><span class="na">BIND_PARAM_STR</span><span class="p">,</span>
    <span class="s2">&quot;year&quot;</span> <span class="o">=&gt;</span> <span class="nx">Column</span><span class="o">::</span><span class="na">BIND_PARAM_INT</span><span class="p">,</span>
<span class="p">];</span>

<span class="c1">// Query robots binding parameters with string placeholders</span>
<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;name = :name: AND year = :year:&quot;</span><span class="p">,</span>
        <span class="s2">&quot;bind&quot;</span>      <span class="o">=&gt;</span> <span class="nv">$parameters</span><span class="p">,</span>
        <span class="s2">&quot;bindTypes&quot;</span> <span class="o">=&gt;</span> <span class="nv">$types</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<blockquote class="highlights">
<div>默认的参数绑定类型是 <code class="code docutils literal"><span class="pre">Phalcon\Db\Column::BIND_PARAM_STR</span></code> , 若所有字段都是string类型，则不用特意去设置参数的“bindTypes”.</div></blockquote>
<p>如果你的绑定参数是array数组，那么数组索引必须从数字0开始:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$array</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;a&quot;</span><span class="p">,</span><span class="s2">&quot;b&quot;</span><span class="p">,</span><span class="s2">&quot;c&quot;</span><span class="p">];</span> <span class="c1">// $array: [[0] =&gt; &quot;a&quot;, [1] =&gt; &quot;b&quot;, [2] =&gt; &quot;c&quot;]</span>

<span class="nb">unset</span><span class="p">(</span><span class="nv">$array</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span> <span class="c1">// $array: [[0] =&gt; &quot;a&quot;, [2] =&gt; &quot;c&quot;]</span>

<span class="c1">// Now we have to renumber the keys</span>
<span class="nv">$array</span> <span class="o">=</span> <span class="nb">array_values</span><span class="p">(</span><span class="nv">$array</span><span class="p">);</span> <span class="c1">// $array: [[0] =&gt; &quot;a&quot;, [1] =&gt; &quot;c&quot;]</span>

<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s1">&#39;letter IN ({letter:array})&#39;</span><span class="p">,</span>
        <span class="s1">&#39;bind&#39;</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="s1">&#39;letter&#39;</span> <span class="o">=&gt;</span> <span class="nv">$array</span>
        <span class="p">]</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<blockquote class="highlights">
<div>参数绑定的方式适用于所有与查询相关的方法，如 <code class="code docutils literal"><span class="pre">find()</span></code> , <code class="code docutils literal"><span class="pre">findFirst()</span></code> 等等,
同时也适用于与计算相关的方法，如 <code class="code docutils literal"><span class="pre">count()</span></code>, <code class="code docutils literal"><span class="pre">sum()</span></code>, <code class="code docutils literal"><span class="pre">average()</span></code> 等等.</div></blockquote>
<p>若使用如下方式，phalcon也会自动为你进行参数绑定:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="c1">// Explicit query using bound parameters</span>
<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;name = ?0&quot;</span><span class="p">,</span>
        <span class="s2">&quot;bind&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="s2">&quot;Ultron&quot;</span><span class="p">,</span>
        <span class="p">],</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="c1">// Implicit query using bound parameters（隐式的参数绑定）</span>
<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findByName</span><span class="p">(</span><span class="s2">&quot;Ultron&quot;</span><span class="p">);</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="initializing-preparing-fetched-records">
<h2>获取记录的初始化以及准备（Initializing/Preparing fetched records）<a class="headerlink" href="#initializing-preparing-fetched-records" title="永久链接至标题">¶</a></h2>
<p>有时从数据库中获取了一条记录之后，在被应用程序使用之前，需要对数据进行初始化。
你可以在模型中实现&#8221;afterFetch&#8221;方法，在模型实例化之后会执行这个方法，并将数据分配给它:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$name</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$status</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">beforeSave</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="c1">// Convert the array into a string</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">status</span> <span class="o">=</span> <span class="nb">join</span><span class="p">(</span><span class="s2">&quot;,&quot;</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">status</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">afterFetch</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="c1">// Convert the string to an array</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">status</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s2">&quot;,&quot;</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">status</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">afterSave</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="c1">// Convert the string to an array</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">status</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s2">&quot;,&quot;</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">status</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>如果使用getters/setters方法代替公共属性的取/赋值，你能在它被调用时，对成员属性进行初始化:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$name</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$status</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">getStatus</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="nb">explode</span><span class="p">(</span><span class="s2">&quot;,&quot;</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">status</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="relationships-between-models">
<h2>模型关系（Relationships between Models）<a class="headerlink" href="#relationships-between-models" title="永久链接至标题">¶</a></h2>
<p>有四种关系类型：1对1,1对多，多对1，多对多。关系可以是单向或者双向的，每个关系可以是简单的（一个1对1的模型）也可以是复杂的（1组模型）。
The model manager manages foreign key constraints for these relationships, the definition of these helps referential
integrity as well as easy and fast access of related records to a model. Through the implementation of relations,
it is easy to access data in related models from each record in a uniform way.</p>
<div class="section" id="unidirectional-relationships">
<h3>单向关系（Unidirectional relationships）<a class="headerlink" href="#unidirectional-relationships" title="永久链接至标题">¶</a></h3>
<p>Unidirectional relations are those that are generated in relation to one another but not vice versa.</p>
</div>
<div class="section" id="bidirectional-relations">
<h3>双向关系（Bidirectional relations）<a class="headerlink" href="#bidirectional-relations" title="永久链接至标题">¶</a></h3>
<p>The bidirectional relations build relationships in both models and each model defines the inverse relationship of the other.</p>
</div>
<div class="section" id="defining-relationships">
<h3>定义关系（Defining relationships）<a class="headerlink" href="#defining-relationships" title="永久链接至标题">¶</a></h3>
<p>In Phalcon, relationships must be defined in the <code class="code docutils literal"><span class="pre">initialize()</span></code> method of a model. The methods <code class="code docutils literal"><span class="pre">belongsTo()</span></code>, <code class="code docutils literal"><span class="pre">hasOne()</span></code>,
<code class="code docutils literal"><span class="pre">hasMany()</span></code> and <code class="code docutils literal"><span class="pre">hasManyToMany()</span></code> define the relationship between one or more fields from the current model to fields in
another model. Each of these methods requires 3 parameters: local fields, referenced model, referenced fields.</p>
<table border="1" class="docutils">
<colgroup>
<col width="35%" />
<col width="65%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Method</th>
<th class="head">Description</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>hasMany</td>
<td>Defines a 1-n relationship</td>
</tr>
<tr class="row-odd"><td>hasOne</td>
<td>Defines a 1-1 relationship</td>
</tr>
<tr class="row-even"><td>belongsTo</td>
<td>Defines a n-1 relationship</td>
</tr>
<tr class="row-odd"><td>hasManyToMany</td>
<td>Defines a n-n relationship</td>
</tr>
</tbody>
</table>
<p>The following schema shows 3 tables whose relations will serve us as an example regarding relationships:</p>
<div class="highlight-sql"><div class="highlight"><pre><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="o">`</span><span class="n">robots</span><span class="o">`</span> <span class="p">(</span>
    <span class="o">`</span><span class="n">id</span><span class="o">`</span> <span class="nb">int</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="n">unsigned</span> <span class="k">NOT</span> <span class="k">NULL</span> <span class="n">AUTO_INCREMENT</span><span class="p">,</span>
    <span class="o">`</span><span class="n">name</span><span class="o">`</span> <span class="nb">varchar</span><span class="p">(</span><span class="mi">70</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
    <span class="o">`</span><span class="k">type</span><span class="o">`</span> <span class="nb">varchar</span><span class="p">(</span><span class="mi">32</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
    <span class="o">`</span><span class="k">year</span><span class="o">`</span> <span class="nb">int</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
    <span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="p">(</span><span class="o">`</span><span class="n">id</span><span class="o">`</span><span class="p">)</span>
<span class="p">);</span>

<span class="k">CREATE</span> <span class="k">TABLE</span> <span class="o">`</span><span class="n">robots_parts</span><span class="o">`</span> <span class="p">(</span>
    <span class="o">`</span><span class="n">id</span><span class="o">`</span> <span class="nb">int</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="n">unsigned</span> <span class="k">NOT</span> <span class="k">NULL</span> <span class="n">AUTO_INCREMENT</span><span class="p">,</span>
    <span class="o">`</span><span class="n">robots_id</span><span class="o">`</span> <span class="nb">int</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
    <span class="o">`</span><span class="n">parts_id</span><span class="o">`</span> <span class="nb">int</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
    <span class="o">`</span><span class="n">created_at</span><span class="o">`</span> <span class="nb">DATE</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
    <span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="p">(</span><span class="o">`</span><span class="n">id</span><span class="o">`</span><span class="p">),</span>
    <span class="k">KEY</span> <span class="o">`</span><span class="n">robots_id</span><span class="o">`</span> <span class="p">(</span><span class="o">`</span><span class="n">robots_id</span><span class="o">`</span><span class="p">),</span>
    <span class="k">KEY</span> <span class="o">`</span><span class="n">parts_id</span><span class="o">`</span> <span class="p">(</span><span class="o">`</span><span class="n">parts_id</span><span class="o">`</span><span class="p">)</span>
<span class="p">);</span>

<span class="k">CREATE</span> <span class="k">TABLE</span> <span class="o">`</span><span class="n">parts</span><span class="o">`</span> <span class="p">(</span>
    <span class="o">`</span><span class="n">id</span><span class="o">`</span> <span class="nb">int</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="n">unsigned</span> <span class="k">NOT</span> <span class="k">NULL</span> <span class="n">AUTO_INCREMENT</span><span class="p">,</span>
    <span class="o">`</span><span class="n">name</span><span class="o">`</span> <span class="nb">varchar</span><span class="p">(</span><span class="mi">70</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
    <span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="p">(</span><span class="o">`</span><span class="n">id</span><span class="o">`</span><span class="p">)</span>
<span class="p">);</span>
</pre></div>
</div>
<ul class="simple">
<li>The model &#8220;Robots&#8221; has many &#8220;RobotsParts&#8221;.</li>
<li>The model &#8220;Parts&#8221; has many &#8220;RobotsParts&#8221;.</li>
<li>The model &#8220;RobotsParts&#8221; belongs to both &#8220;Robots&#8221; and &#8220;Parts&#8221; models as a many-to-one relation.</li>
<li>The model &#8220;Robots&#8221; has a relation many-to-many to &#8220;Parts&#8221; through &#8220;RobotsParts&#8221;.</li>
</ul>
<p>Check the EER diagram to understand better the relations:</p>
<div class="figure align-center">
<img alt="../images/eer-1.png" src="../images/eer-1.png" />
</div>
<p>The models with their relations could be implemented as follows:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$name</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">hasMany</span><span class="p">(</span>
            <span class="s2">&quot;id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;RobotsParts&quot;</span><span class="p">,</span>
            <span class="s2">&quot;robots_id&quot;</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Parts</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$name</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">hasMany</span><span class="p">(</span>
            <span class="s2">&quot;id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;RobotsParts&quot;</span><span class="p">,</span>
            <span class="s2">&quot;parts_id&quot;</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">RobotsParts</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$robots_id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$parts_id</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">belongsTo</span><span class="p">(</span>
            <span class="s2">&quot;robots_id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;Store</span><span class="se">\\</span><span class="s2">Toys</span><span class="se">\\</span><span class="s2">Robots&quot;</span><span class="p">,</span>
            <span class="s2">&quot;id&quot;</span>
        <span class="p">);</span>

        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">belongsTo</span><span class="p">(</span>
            <span class="s2">&quot;parts_id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;Parts&quot;</span><span class="p">,</span>
            <span class="s2">&quot;id&quot;</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The first parameter indicates the field of the local model used in the relationship; the second indicates the name
of the referenced model and the third the field name in the referenced model. You could also use arrays to define multiple fields in the relationship.</p>
<p>Many to many relationships require 3 models and define the attributes involved in the relationship:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$name</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">hasManyToMany</span><span class="p">(</span>
            <span class="s2">&quot;id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;RobotsParts&quot;</span><span class="p">,</span>
            <span class="s2">&quot;robots_id&quot;</span><span class="p">,</span> <span class="s2">&quot;parts_id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;Parts&quot;</span><span class="p">,</span>
            <span class="s2">&quot;id&quot;</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="taking-advantage-of-relationships">
<h3>使用关系（Taking advantage of relationships）<a class="headerlink" href="#taking-advantage-of-relationships" title="永久链接至标题">¶</a></h3>
<p>When explicitly defining the relationships between models, it is easy to find related records for a particular record.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">robotsParts</span> <span class="k">as</span> <span class="nv">$robotPart</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="nv">$robotPart</span><span class="o">-&gt;</span><span class="na">parts</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Phalcon uses the magic methods <code class="code docutils literal"><span class="pre">__set</span></code>/<code class="code docutils literal"><span class="pre">__get</span></code>/<code class="code docutils literal"><span class="pre">__call</span></code> to store or retrieve related data using relationships.</p>
<p>By accessing an attribute with the same name as the relationship will retrieve all its related record(s).</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">();</span>

<span class="c1">// All the related records in RobotsParts</span>
<span class="nv">$robotsParts</span> <span class="o">=</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">robotsParts</span><span class="p">;</span>
</pre></div>
</div>
<p>Also, you can use a magic getter:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">();</span>

<span class="c1">// All the related records in RobotsParts</span>
<span class="nv">$robotsParts</span> <span class="o">=</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">getRobotsParts</span><span class="p">();</span>

<span class="c1">// Passing parameters</span>
<span class="nv">$robotsParts</span> <span class="o">=</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">getRobotsParts</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;limit&quot;</span> <span class="o">=&gt;</span> <span class="mi">5</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<p>If the called method has a &#8220;get&#8221; prefix <a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> will return a
<code class="code docutils literal"><span class="pre">findFirst()</span></code>/<code class="code docutils literal"><span class="pre">find()</span></code> result. The following example compares retrieving related results with using magic methods
and without:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>

<span class="c1">// Robots model has a 1-n (hasMany)</span>
<span class="c1">// relationship to RobotsParts then</span>
<span class="nv">$robotsParts</span> <span class="o">=</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">robotsParts</span><span class="p">;</span>

<span class="c1">// Only parts that match conditions</span>
<span class="nv">$robotsParts</span> <span class="o">=</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">getRobotsParts</span><span class="p">(</span><span class="s2">&quot;created_at = &#39;2015-03-15&#39;&quot;</span><span class="p">);</span>

<span class="c1">// Or using bound parameters</span>
<span class="nv">$robotsParts</span> <span class="o">=</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">getRobotsParts</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;created_at = :date:&quot;</span><span class="p">,</span>
        <span class="s2">&quot;bind&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="s2">&quot;date&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;2015-03-15&quot;</span>
        <span class="p">]</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="nv">$robotPart</span> <span class="o">=</span> <span class="nx">RobotsParts</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>

<span class="c1">// RobotsParts model has a n-1 (belongsTo)</span>
<span class="c1">// relationship to RobotsParts then</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nv">$robotPart</span><span class="o">-&gt;</span><span class="na">robots</span><span class="p">;</span>
</pre></div>
</div>
<p>Getting related records manually:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>

<span class="c1">// Robots model has a 1-n (hasMany)</span>
<span class="c1">// relationship to RobotsParts, then</span>
<span class="nv">$robotsParts</span> <span class="o">=</span> <span class="nx">RobotsParts</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="s2">&quot;robots_id = &#39;&quot;</span> <span class="o">.</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">id</span> <span class="o">.</span> <span class="s2">&quot;&#39;&quot;</span>
<span class="p">);</span>

<span class="c1">// Only parts that match conditions</span>
<span class="nv">$robotsParts</span> <span class="o">=</span> <span class="nx">RobotsParts</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="s2">&quot;robots_id = &#39;&quot;</span> <span class="o">.</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">id</span> <span class="o">.</span> <span class="s2">&quot;&#39; AND created_at = &#39;2015-03-15&#39;&quot;</span>
<span class="p">);</span>

<span class="nv">$robotPart</span> <span class="o">=</span> <span class="nx">RobotsParts</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>

<span class="c1">// RobotsParts model has a n-1 (belongsTo)</span>
<span class="c1">// relationship to RobotsParts then</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span>
    <span class="s2">&quot;id = &#39;&quot;</span> <span class="o">.</span> <span class="nv">$robotPart</span><span class="o">-&gt;</span><span class="na">robots_id</span> <span class="o">.</span> <span class="s2">&quot;&#39;&quot;</span>
<span class="p">);</span>
</pre></div>
</div>
<p>The prefix &#8220;get&#8221; is used to <code class="code docutils literal"><span class="pre">find()</span></code>/<code class="code docutils literal"><span class="pre">findFirst()</span></code> related records. Depending on the type of relation it will use
<code class="code docutils literal"><span class="pre">find()</span></code> or <code class="code docutils literal"><span class="pre">findFirst()</span></code>:</p>
<table border="1" class="docutils">
<colgroup>
<col width="12%" />
<col width="73%" />
<col width="14%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Type</th>
<th class="head">Description</th>
<th class="head">Implicit Method</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>Belongs-To</td>
<td>Returns a model instance of the related record directly</td>
<td>findFirst</td>
</tr>
<tr class="row-odd"><td>Has-One</td>
<td>Returns a model instance of the related record directly</td>
<td>findFirst</td>
</tr>
<tr class="row-even"><td>Has-Many</td>
<td>Returns a collection of model instances of the referenced model</td>
<td>find</td>
</tr>
<tr class="row-odd"><td>Has-Many-to-Many</td>
<td>Returns a collection of model instances of the referenced model, it implicitly does &#8216;inner joins&#8217; with the involved models</td>
<td>(complex query)</td>
</tr>
</tbody>
</table>
<p>You can also use the &#8220;count&#8221; prefix to return an integer denoting the count of the related records:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>

<span class="k">echo</span> <span class="s2">&quot;The robot has &quot;</span><span class="p">,</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">countRobotsParts</span><span class="p">(),</span> <span class="s2">&quot; parts</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
</pre></div>
</div>
</div>
<div class="section" id="aliasing-relationships">
<h3>定义关系（Aliasing Relationships）<a class="headerlink" href="#aliasing-relationships" title="永久链接至标题">¶</a></h3>
<p>To explain better how aliases work, let&#8217;s check the following example:</p>
<p>The &#8220;robots_similar&#8221; table has the function to define what robots are similar to others:</p>
<div class="highlight-bash"><div class="highlight"><pre>mysql&gt; desc robots_similar<span class="p">;</span>
+-------------------+------------------+------+-----+---------+----------------+
<span class="p">|</span> Field             <span class="p">|</span> Type             <span class="p">|</span> Null <span class="p">|</span> Key <span class="p">|</span> Default <span class="p">|</span> Extra          <span class="p">|</span>
+-------------------+------------------+------+-----+---------+----------------+
<span class="p">|</span> id                <span class="p">|</span> int<span class="o">(</span>10<span class="o">)</span> unsigned <span class="p">|</span> NO   <span class="p">|</span> PRI <span class="p">|</span> NULL    <span class="p">|</span> auto_increment <span class="p">|</span>
<span class="p">|</span> robots_id         <span class="p">|</span> int<span class="o">(</span>10<span class="o">)</span> unsigned <span class="p">|</span> NO   <span class="p">|</span> MUL <span class="p">|</span> NULL    <span class="p">|</span>                <span class="p">|</span>
<span class="p">|</span> similar_robots_id <span class="p">|</span> int<span class="o">(</span>10<span class="o">)</span> unsigned <span class="p">|</span> NO   <span class="p">|</span>     <span class="p">|</span> NULL    <span class="p">|</span>                <span class="p">|</span>
+-------------------+------------------+------+-----+---------+----------------+
<span class="m">3</span> rows in <span class="nb">set</span> <span class="o">(</span>0.00 sec<span class="o">)</span>
</pre></div>
</div>
<p>Both &#8220;robots_id&#8221; and &#8220;similar_robots_id&#8221; have a relation to the model Robots:</p>
<div class="figure align-center">
<img alt="../images/eer-2.png" src="../images/eer-2.png" />
</div>
<p>A model that maps this table and its relationships is the following:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">class</span> <span class="nc">RobotsSimilar</span> <span class="k">extends</span> <span class="nx">Phalcon\Mvc\Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">belongsTo</span><span class="p">(</span>
            <span class="s2">&quot;robots_id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;Store</span><span class="se">\\</span><span class="s2">Toys</span><span class="se">\\</span><span class="s2">Robots&quot;</span><span class="p">,</span>
            <span class="s2">&quot;id&quot;</span>
        <span class="p">);</span>

        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">belongsTo</span><span class="p">(</span>
            <span class="s2">&quot;similar_robots_id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;Store</span><span class="se">\\</span><span class="s2">Toys</span><span class="se">\\</span><span class="s2">Robots&quot;</span><span class="p">,</span>
            <span class="s2">&quot;id&quot;</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Since both relations point to the same model (Robots), obtain the records related to the relationship could not be clear:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$robotsSimilar</span> <span class="o">=</span> <span class="nx">RobotsSimilar</span><span class="o">::</span><span class="na">findFirst</span><span class="p">();</span>

<span class="c1">// Returns the related record based on the column (robots_id)</span>
<span class="c1">// Also as is a belongsTo it&#39;s only returning one record</span>
<span class="c1">// but the name &#39;getRobots&#39; seems to imply that return more than one</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nv">$robotsSimilar</span><span class="o">-&gt;</span><span class="na">getRobots</span><span class="p">();</span>

<span class="c1">// but, how to get the related record based on the column (similar_robots_id)</span>
<span class="c1">// if both relationships have the same name?</span>
</pre></div>
</div>
<p>The aliases allow us to rename both relationships to solve these problems:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">RobotsSimilar</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">belongsTo</span><span class="p">(</span>
            <span class="s2">&quot;robots_id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;Store</span><span class="se">\\</span><span class="s2">Toys</span><span class="se">\\</span><span class="s2">Robots&quot;</span><span class="p">,</span>
            <span class="s2">&quot;id&quot;</span><span class="p">,</span>
            <span class="p">[</span>
                <span class="s2">&quot;alias&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;Robot&quot;</span><span class="p">,</span>
            <span class="p">]</span>
        <span class="p">);</span>

        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">belongsTo</span><span class="p">(</span>
            <span class="s2">&quot;similar_robots_id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;Store</span><span class="se">\\</span><span class="s2">Toys</span><span class="se">\\</span><span class="s2">Robots&quot;</span><span class="p">,</span>
            <span class="s2">&quot;id&quot;</span><span class="p">,</span>
            <span class="p">[</span>
                <span class="s2">&quot;alias&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;SimilarRobot&quot;</span><span class="p">,</span>
            <span class="p">]</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>With the aliasing we can get the related records easily:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$robotsSimilar</span> <span class="o">=</span> <span class="nx">RobotsSimilar</span><span class="o">::</span><span class="na">findFirst</span><span class="p">();</span>

<span class="c1">// Returns the related record based on the column (robots_id)</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nv">$robotsSimilar</span><span class="o">-&gt;</span><span class="na">getRobot</span><span class="p">();</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nv">$robotsSimilar</span><span class="o">-&gt;</span><span class="na">robot</span><span class="p">;</span>

<span class="c1">// Returns the related record based on the column (similar_robots_id)</span>
<span class="nv">$similarRobot</span> <span class="o">=</span> <span class="nv">$robotsSimilar</span><span class="o">-&gt;</span><span class="na">getSimilarRobot</span><span class="p">();</span>
<span class="nv">$similarRobot</span> <span class="o">=</span> <span class="nv">$robotsSimilar</span><span class="o">-&gt;</span><span class="na">similarRobot</span><span class="p">;</span>
</pre></div>
</div>
</div>
<div class="section" id="getters-magic-getters-vs-explicit-methods">
<h3>魔术方法 Getters 对比显示方法（Magic Getters vs. Explicit methods）<a class="headerlink" href="#getters-magic-getters-vs-explicit-methods" title="永久链接至标题">¶</a></h3>
<p>Most IDEs and editors with auto-completion capabilities can not infer the correct types when using magic getters,
instead of use the magic getters you can optionally define those methods explicitly with the corresponding
docblocks helping the IDE to produce a better auto-completion:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$name</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">hasMany</span><span class="p">(</span>
            <span class="s2">&quot;id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;RobotsParts&quot;</span><span class="p">,</span>
            <span class="s2">&quot;robots_id&quot;</span>
        <span class="p">);</span>
    <span class="p">}</span>

    <span class="sd">/**</span>
<span class="sd">     * Return the related &quot;robots parts&quot;</span>
<span class="sd">     *</span>
<span class="sd">     * @return \RobotsParts[]</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">getRobotsParts</span><span class="p">(</span><span class="nv">$parameters</span> <span class="o">=</span> <span class="k">null</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getRelated</span><span class="p">(</span><span class="s2">&quot;RobotsParts&quot;</span><span class="p">,</span> <span class="nv">$parameters</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="virtual-foreign-keys">
<h2>虚拟外键（Virtual Foreign Keys）<a class="headerlink" href="#virtual-foreign-keys" title="永久链接至标题">¶</a></h2>
<p>By default, relationships do not act like database foreign keys, that is, if you try to insert/update a value without having a valid
value in the referenced model, Phalcon will not produce a validation message. You can modify this behavior by adding a fourth parameter
when defining a relationship.</p>
<p>The RobotsPart model can be changed to demonstrate this feature:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">RobotsParts</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$robots_id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$parts_id</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">belongsTo</span><span class="p">(</span>
            <span class="s2">&quot;robots_id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;Store</span><span class="se">\\</span><span class="s2">Toys</span><span class="se">\\</span><span class="s2">Robots&quot;</span><span class="p">,</span>
            <span class="s2">&quot;id&quot;</span><span class="p">,</span>
            <span class="p">[</span>
                <span class="s2">&quot;foreignKey&quot;</span> <span class="o">=&gt;</span> <span class="k">true</span>
            <span class="p">]</span>
        <span class="p">);</span>

        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">belongsTo</span><span class="p">(</span>
            <span class="s2">&quot;parts_id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;Parts&quot;</span><span class="p">,</span>
            <span class="s2">&quot;id&quot;</span><span class="p">,</span>
            <span class="p">[</span>
                <span class="s2">&quot;foreignKey&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
                    <span class="s2">&quot;message&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;The part_id does not exist on the Parts model&quot;</span>
                <span class="p">]</span>
            <span class="p">]</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>If you alter a <code class="code docutils literal"><span class="pre">belongsTo()</span></code> relationship to act as foreign key, it will validate that the values inserted/updated on those fields have a
valid value on the referenced model. Similarly, if a <code class="code docutils literal"><span class="pre">hasMany()</span></code>/<code class="code docutils literal"><span class="pre">hasOne()</span></code> is altered it will validate that the records cannot be deleted
if that record is used on a referenced model.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Parts</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">hasMany</span><span class="p">(</span>
            <span class="s2">&quot;id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;RobotsParts&quot;</span><span class="p">,</span>
            <span class="s2">&quot;parts_id&quot;</span><span class="p">,</span>
            <span class="p">[</span>
                <span class="s2">&quot;foreignKey&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
                    <span class="s2">&quot;message&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;The part cannot be deleted because other robots are using it&quot;</span><span class="p">,</span>
                <span class="p">]</span>
            <span class="p">]</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>A virtual foreign key can be set up to allow null values as follows:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">RobotsParts</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$robots_id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$parts_id</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">belongsTo</span><span class="p">(</span>
            <span class="s2">&quot;parts_id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;Parts&quot;</span><span class="p">,</span>
            <span class="s2">&quot;id&quot;</span><span class="p">,</span>
            <span class="p">[</span>
                <span class="s2">&quot;foreignKey&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
                    <span class="s2">&quot;allowNulls&quot;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span>
                    <span class="s2">&quot;message&quot;</span>    <span class="o">=&gt;</span> <span class="s2">&quot;The part_id does not exist on the Parts model&quot;</span><span class="p">,</span>
                <span class="p">]</span>
            <span class="p">]</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="section" id="cascade-restrict-actions">
<h3>级联与限制动作（Cascade/Restrict actions）<a class="headerlink" href="#cascade-restrict-actions" title="永久链接至标题">¶</a></h3>
<p>Relationships that act as virtual foreign keys by default restrict the creation/update/deletion of records
to maintain the integrity of data:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model\Relation</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$name</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">hasMany</span><span class="p">(</span>
            <span class="s2">&quot;id&quot;</span><span class="p">,</span>
            <span class="s2">&quot;Parts&quot;</span><span class="p">,</span>
            <span class="s2">&quot;robots_id&quot;</span><span class="p">,</span>
            <span class="p">[</span>
                <span class="s2">&quot;foreignKey&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
                    <span class="s2">&quot;action&quot;</span> <span class="o">=&gt;</span> <span class="nx">Relation</span><span class="o">::</span><span class="na">ACTION_CASCADE</span><span class="p">,</span>
                <span class="p">]</span>
            <span class="p">]</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The above code set up to delete all the referenced records (parts) if the master record (robot) is deleted.</p>
</div>
</div>
<div class="section" id="generating-calculations">
<h2>生成运算（Generating Calculations）<a class="headerlink" href="#generating-calculations" title="永久链接至标题">¶</a></h2>
<p>Calculations (or aggregations) are helpers for commonly used functions of database systems such as COUNT, SUM, MAX, MIN or AVG.
<a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> allows to use these functions directly from the exposed methods.</p>
<p>Count examples:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">// How many employees are?</span>
<span class="nv">$rowcount</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">count</span><span class="p">();</span>

<span class="c1">// How many different areas are assigned to employees?</span>
<span class="nv">$rowcount</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">count</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;distinct&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;area&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="c1">// How many employees are in the Testing area?</span>
<span class="nv">$rowcount</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">count</span><span class="p">(</span>
    <span class="s2">&quot;area = &#39;Testing&#39;&quot;</span>
<span class="p">);</span>

<span class="c1">// Count employees grouping results by their area</span>
<span class="nv">$group</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">count</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;group&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;area&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$group</span> <span class="k">as</span> <span class="nv">$row</span><span class="p">)</span> <span class="p">{</span>
   <span class="k">echo</span> <span class="s2">&quot;There are &quot;</span><span class="p">,</span> <span class="nv">$row</span><span class="o">-&gt;</span><span class="na">rowcount</span><span class="p">,</span> <span class="s2">&quot; in &quot;</span><span class="p">,</span> <span class="nv">$row</span><span class="o">-&gt;</span><span class="na">area</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// Count employees grouping by their area and ordering the result by count</span>
<span class="nv">$group</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">count</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;group&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;area&quot;</span><span class="p">,</span>
        <span class="s2">&quot;order&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;rowcount&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="c1">// Avoid SQL injections using bound parameters</span>
<span class="nv">$group</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">count</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;type &gt; ?0&quot;</span><span class="p">,</span>
        <span class="s2">&quot;bind&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="nv">$type</span>
        <span class="p">],</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<p>Sum examples:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">// How much are the salaries of all employees?</span>
<span class="nv">$total</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">sum</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;column&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;salary&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="c1">// How much are the salaries of all employees in the Sales area?</span>
<span class="nv">$total</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">sum</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;column&quot;</span>     <span class="o">=&gt;</span> <span class="s2">&quot;salary&quot;</span><span class="p">,</span>
        <span class="s2">&quot;conditions&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;area = &#39;Sales&#39;&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="c1">// Generate a grouping of the salaries of each area</span>
<span class="nv">$group</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">sum</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;column&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;salary&quot;</span><span class="p">,</span>
        <span class="s2">&quot;group&quot;</span>  <span class="o">=&gt;</span> <span class="s2">&quot;area&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$group</span> <span class="k">as</span> <span class="nv">$row</span><span class="p">)</span> <span class="p">{</span>
   <span class="k">echo</span> <span class="s2">&quot;The sum of salaries of the &quot;</span><span class="p">,</span> <span class="nv">$row</span><span class="o">-&gt;</span><span class="na">area</span><span class="p">,</span> <span class="s2">&quot; is &quot;</span><span class="p">,</span> <span class="nv">$row</span><span class="o">-&gt;</span><span class="na">sumatory</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// Generate a grouping of the salaries of each area ordering</span>
<span class="c1">// salaries from higher to lower</span>
<span class="nv">$group</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">sum</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;column&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;salary&quot;</span><span class="p">,</span>
        <span class="s2">&quot;group&quot;</span>  <span class="o">=&gt;</span> <span class="s2">&quot;area&quot;</span><span class="p">,</span>
        <span class="s2">&quot;order&quot;</span>  <span class="o">=&gt;</span> <span class="s2">&quot;sumatory DESC&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="c1">// Avoid SQL injections using bound parameters</span>
<span class="nv">$group</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">sum</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;conditions&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;area &gt; ?0&quot;</span><span class="p">,</span>
        <span class="s2">&quot;bind&quot;</span>       <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="nv">$area</span>
        <span class="p">],</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<p>Average examples:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">// What is the average salary for all employees?</span>
<span class="nv">$average</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">average</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;column&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;salary&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="c1">// What is the average salary for the Sales&#39;s area employees?</span>
<span class="nv">$average</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">average</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;column&quot;</span>     <span class="o">=&gt;</span> <span class="s2">&quot;salary&quot;</span><span class="p">,</span>
        <span class="s2">&quot;conditions&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;area = &#39;Sales&#39;&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="c1">// Avoid SQL injections using bound parameters</span>
<span class="nv">$average</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">average</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;column&quot;</span>     <span class="o">=&gt;</span> <span class="s2">&quot;age&quot;</span><span class="p">,</span>
        <span class="s2">&quot;conditions&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;area &gt; ?0&quot;</span><span class="p">,</span>
        <span class="s2">&quot;bind&quot;</span>       <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="nv">$area</span>
        <span class="p">],</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<p>Max/Min examples:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">// What is the oldest age of all employees?</span>
<span class="nv">$age</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">maximum</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;column&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;age&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="c1">// What is the oldest of employees from the Sales area?</span>
<span class="nv">$age</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">maximum</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;column&quot;</span>     <span class="o">=&gt;</span> <span class="s2">&quot;age&quot;</span><span class="p">,</span>
        <span class="s2">&quot;conditions&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;area = &#39;Sales&#39;&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="c1">// What is the lowest salary of all employees?</span>
<span class="nv">$salary</span> <span class="o">=</span> <span class="nx">Employees</span><span class="o">::</span><span class="na">minimum</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;column&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;salary&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="hydration-modes">
<h2>Hydration Modes<a class="headerlink" href="#hydration-modes" title="永久链接至标题">¶</a></h2>
<p>As mentioned above, resultsets are collections of complete objects, this means that every returned result is an object
representing a row in the database. These objects can be modified and saved again to persistence:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">();</span>

<span class="c1">// Manipulating a resultset of complete objects</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$robots</span> <span class="k">as</span> <span class="nv">$robot</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">year</span> <span class="o">=</span> <span class="mi">2000</span><span class="p">;</span>

    <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">save</span><span class="p">();</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Sometimes records are obtained only to be presented to a user in read-only mode, in these cases it may be useful
to change the way in which records are represented to facilitate their handling. The strategy used to represent objects
returned in a resultset is called &#8216;hydration mode&#8217;:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model\Resultset</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">();</span>

<span class="c1">// Return every robot as an array</span>
<span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">setHydrateMode</span><span class="p">(</span>
    <span class="nx">Resultset</span><span class="o">::</span><span class="na">HYDRATE_ARRAYS</span>
<span class="p">);</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$robots</span> <span class="k">as</span> <span class="nv">$robot</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="nv">$robot</span><span class="p">[</span><span class="s2">&quot;year&quot;</span><span class="p">],</span> <span class="nx">PHP_EOL</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// Return every robot as a stdClass</span>
<span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">setHydrateMode</span><span class="p">(</span>
    <span class="nx">Resultset</span><span class="o">::</span><span class="na">HYDRATE_OBJECTS</span>
<span class="p">);</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$robots</span> <span class="k">as</span> <span class="nv">$robot</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">year</span><span class="p">,</span> <span class="nx">PHP_EOL</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// Return every robot as a Robots instance</span>
<span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">setHydrateMode</span><span class="p">(</span>
    <span class="nx">Resultset</span><span class="o">::</span><span class="na">HYDRATE_RECORDS</span>
<span class="p">);</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$robots</span> <span class="k">as</span> <span class="nv">$robot</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">year</span><span class="p">,</span> <span class="nx">PHP_EOL</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Hydration mode can also be passed as a parameter of &#8216;find&#8217;:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model\Resultset</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;hydration&quot;</span> <span class="o">=&gt;</span> <span class="nx">Resultset</span><span class="o">::</span><span class="na">HYDRATE_ARRAYS</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$robots</span> <span class="k">as</span> <span class="nv">$robot</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="nv">$robot</span><span class="p">[</span><span class="s2">&quot;year&quot;</span><span class="p">],</span> <span class="nx">PHP_EOL</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="creating-updating-records">
<h2>创建与更新记录（Creating/Updating Records）<a class="headerlink" href="#creating-updating-records" title="永久链接至标题">¶</a></h2>
<p>The <code class="code docutils literal"><span class="pre">Phalcon\Mvc\Model::save()</span></code> method allows you to create/update records according to whether they already exist in the table
associated with a model. The save method is called internally by the create and update methods of <a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a>.
For this to work as expected it is necessary to have properly defined a primary key in the entity to determine whether a record
should be updated or created.</p>
<p>Also the method executes associated validators, virtual foreign keys and events that are defined in the model:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Robots</span><span class="p">();</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">type</span> <span class="o">=</span> <span class="s2">&quot;mechanical&quot;</span><span class="p">;</span>
<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="s2">&quot;Astro Boy&quot;</span><span class="p">;</span>
<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">year</span> <span class="o">=</span> <span class="mi">1952</span><span class="p">;</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">save</span><span class="p">()</span> <span class="o">===</span> <span class="k">false</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s2">&quot;Umh, We can&#39;t store robots right now: </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>

    <span class="nv">$messages</span> <span class="o">=</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">getMessages</span><span class="p">();</span>

    <span class="k">foreach</span> <span class="p">(</span><span class="nv">$messages</span> <span class="k">as</span> <span class="nv">$message</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="nv">$message</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s2">&quot;Great, a new robot was saved successfully!&quot;</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>An array could be passed to &#8220;save&#8221; to avoid assign every column manually. <a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> will check if there are setters implemented for
the columns passed in the array giving priority to them instead of assign directly the values of the attributes:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Robots</span><span class="p">();</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">save</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;type&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;mechanical&quot;</span><span class="p">,</span>
        <span class="s2">&quot;name&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;Astro Boy&quot;</span><span class="p">,</span>
        <span class="s2">&quot;year&quot;</span> <span class="o">=&gt;</span> <span class="mi">1952</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<p>Values assigned directly or via the array of attributes are escaped/sanitized according to the related attribute data type. So you can pass
an insecure array without worrying about possible SQL injections:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Robots</span><span class="p">();</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">save</span><span class="p">(</span><span class="nv">$_POST</span><span class="p">);</span>
</pre></div>
</div>
<blockquote class="highlights">
<div>Without precautions mass assignment could allow attackers to set any database column&#8217;s value. Only use this feature
if you want to permit a user to insert/update every column in the model, even if those fields are not in the submitted
form.</div></blockquote>
<p>You can set an additional parameter in &#8216;save&#8217; to set a whitelist of fields that only must taken into account when doing
the mass assignment:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Robots</span><span class="p">();</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">save</span><span class="p">(</span>
    <span class="nv">$_POST</span><span class="p">,</span>
    <span class="p">[</span>
        <span class="s2">&quot;name&quot;</span><span class="p">,</span>
        <span class="s2">&quot;type&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<div class="section" id="create-update-with-confidence">
<h3>创建与更新结果判断（Create/Update with Confidence）<a class="headerlink" href="#create-update-with-confidence" title="永久链接至标题">¶</a></h3>
<p>When an application has a lot of competition, we could be expecting create a record but it is actually updated. This
could happen if we use <code class="code docutils literal"><span class="pre">Phalcon\Mvc\Model::save()</span></code> to persist the records in the database. If we want to be absolutely
sure that a record is created or updated, we can change the <code class="code docutils literal"><span class="pre">save()</span></code> call with <code class="code docutils literal"><span class="pre">create()</span></code> or <code class="code docutils literal"><span class="pre">update()</span></code>:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Robots</span><span class="p">();</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">type</span> <span class="o">=</span> <span class="s2">&quot;mechanical&quot;</span><span class="p">;</span>
<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="s2">&quot;Astro Boy&quot;</span><span class="p">;</span>
<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">year</span> <span class="o">=</span> <span class="mi">1952</span><span class="p">;</span>

<span class="c1">// This record only must be created</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">create</span><span class="p">()</span> <span class="o">===</span> <span class="k">false</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s2">&quot;Umh, We can&#39;t store robots right now: </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>

    <span class="nv">$messages</span> <span class="o">=</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">getMessages</span><span class="p">();</span>

    <span class="k">foreach</span> <span class="p">(</span><span class="nv">$messages</span> <span class="k">as</span> <span class="nv">$message</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="nv">$message</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s2">&quot;Great, a new robot was created successfully!&quot;</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>These methods &#8220;create&#8221; and &#8220;update&#8221; also accept an array of values as parameter.</p>
</div>
<div class="section" id="auto-generated-identity-columns">
<h3>自动生成标识列（Auto-generated identity columns）<a class="headerlink" href="#auto-generated-identity-columns" title="永久链接至标题">¶</a></h3>
<p>Some models may have identity columns. These columns usually are the primary key of the mapped table. <a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a>
can recognize the identity column omitting it in the generated SQL INSERT, so the database system can generate an auto-generated value for it.
Always after creating a record, the identity field will be registered with the value generated in the database system for it:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">save</span><span class="p">();</span>

<span class="k">echo</span> <span class="s2">&quot;The generated id is: &quot;</span><span class="p">,</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">id</span><span class="p">;</span>
</pre></div>
</div>
<p><a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> is able to recognize the identity column. Depending on the database system, those columns may be
serial columns like in PostgreSQL or auto_increment columns in the case of MySQL.</p>
<p>PostgreSQL uses sequences to generate auto-numeric values, by default, Phalcon tries to obtain the generated value from the sequence &#8220;table_field_seq&#8221;,
for example: robots_id_seq, if that sequence has a different name, the <code class="code docutils literal"><span class="pre">getSequenceName()</span></code> method needs to be implemented:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">getSequenceName</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="s2">&quot;robots_sequence_name&quot;</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="storing-related-records">
<h3>存储关系记录（Storing related records）<a class="headerlink" href="#storing-related-records" title="永久链接至标题">¶</a></h3>
<p>Magic properties can be used to store a records and its related properties:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">// Create an artist</span>
<span class="nv">$artist</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Artists</span><span class="p">();</span>

<span class="nv">$artist</span><span class="o">-&gt;</span><span class="na">name</span>    <span class="o">=</span> <span class="s2">&quot;Shinichi Osawa&quot;</span><span class="p">;</span>
<span class="nv">$artist</span><span class="o">-&gt;</span><span class="na">country</span> <span class="o">=</span> <span class="s2">&quot;Japan&quot;</span><span class="p">;</span>

<span class="c1">// Create an album</span>
<span class="nv">$album</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Albums</span><span class="p">();</span>

<span class="nv">$album</span><span class="o">-&gt;</span><span class="na">name</span>   <span class="o">=</span> <span class="s2">&quot;The One&quot;</span><span class="p">;</span>
<span class="nv">$album</span><span class="o">-&gt;</span><span class="na">artist</span> <span class="o">=</span> <span class="nv">$artist</span><span class="p">;</span> <span class="c1">// Assign the artist</span>
<span class="nv">$album</span><span class="o">-&gt;</span><span class="na">year</span>   <span class="o">=</span> <span class="mi">2008</span><span class="p">;</span>

<span class="c1">// Save both records</span>
<span class="nv">$album</span><span class="o">-&gt;</span><span class="na">save</span><span class="p">();</span>
</pre></div>
</div>
<p>Saving a record and its related records in a has-many relation:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">// Get an existing artist</span>
<span class="nv">$artist</span> <span class="o">=</span> <span class="nx">Artists</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span>
    <span class="s2">&quot;name = &#39;Shinichi Osawa&#39;&quot;</span>
<span class="p">);</span>

<span class="c1">// Create an album</span>
<span class="nv">$album</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Albums</span><span class="p">();</span>

<span class="nv">$album</span><span class="o">-&gt;</span><span class="na">name</span>   <span class="o">=</span> <span class="s2">&quot;The One&quot;</span><span class="p">;</span>
<span class="nv">$album</span><span class="o">-&gt;</span><span class="na">artist</span> <span class="o">=</span> <span class="nv">$artist</span><span class="p">;</span>

<span class="nv">$songs</span> <span class="o">=</span> <span class="p">[];</span>

<span class="c1">// Create a first song</span>
<span class="nv">$songs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>           <span class="o">=</span> <span class="k">new</span> <span class="nx">Songs</span><span class="p">();</span>
<span class="nv">$songs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">-&gt;</span><span class="na">name</span>     <span class="o">=</span> <span class="s2">&quot;Star Guitar&quot;</span><span class="p">;</span>
<span class="nv">$songs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">-&gt;</span><span class="na">duration</span> <span class="o">=</span> <span class="s2">&quot;5:54&quot;</span><span class="p">;</span>

<span class="c1">// Create a second song</span>
<span class="nv">$songs</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>           <span class="o">=</span> <span class="k">new</span> <span class="nx">Songs</span><span class="p">();</span>
<span class="nv">$songs</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">-&gt;</span><span class="na">name</span>     <span class="o">=</span> <span class="s2">&quot;Last Days&quot;</span><span class="p">;</span>
<span class="nv">$songs</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">-&gt;</span><span class="na">duration</span> <span class="o">=</span> <span class="s2">&quot;4:29&quot;</span><span class="p">;</span>

<span class="c1">// Assign the songs array</span>
<span class="nv">$album</span><span class="o">-&gt;</span><span class="na">songs</span> <span class="o">=</span> <span class="nv">$songs</span><span class="p">;</span>

<span class="c1">// Save the album + its songs</span>
<span class="nv">$album</span><span class="o">-&gt;</span><span class="na">save</span><span class="p">();</span>
</pre></div>
</div>
<p>Saving the album and the artist at the same time implicitly makes use of a transaction so if anything
goes wrong with saving the related records, the parent will not be saved either. Messages are
passed back to the user for information regarding any errors.</p>
<p>Note: Adding related entities by overloading the following methods is not possible:</p>
<blockquote>
<div><ul class="simple">
<li><code class="code docutils literal"><span class="pre">Phalcon\Mvc\Model::beforeSave()</span></code></li>
<li><code class="code docutils literal"><span class="pre">Phalcon\Mvc\Model::beforeCreate()</span></code></li>
<li><code class="code docutils literal"><span class="pre">Phalcon\Mvc\Model::beforeUpdate()</span></code></li>
</ul>
</div></blockquote>
<p>You need to overload <code class="code docutils literal"><span class="pre">Phalcon\Mvc\Model::save()</span></code> for this to work from within a model.</p>
</div>
<div class="section" id="validation-messages">
<h3>验证信息（Validation Messages）<a class="headerlink" href="#validation-messages" title="永久链接至标题">¶</a></h3>
<p><a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> has a messaging subsystem that provides a flexible way to output or store the
validation messages generated during the insert/update processes.</p>
<p>Each message consists of an instance of the class <a class="reference internal" href="../api/Phalcon_Mvc_Model_Message.html"><em>Phalcon\Mvc\Model\Message</em></a>. The set of
messages generated can be retrieved with the <code class="code docutils literal"><span class="pre">getMessages()</span></code> method. Each message provides extended information like the field name that
generated the message or the message type:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">save</span><span class="p">()</span> <span class="o">===</span> <span class="k">false</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$messages</span> <span class="o">=</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">getMessages</span><span class="p">();</span>

    <span class="k">foreach</span> <span class="p">(</span><span class="nv">$messages</span> <span class="k">as</span> <span class="nv">$message</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">&quot;Message: &quot;</span><span class="p">,</span> <span class="nv">$message</span><span class="o">-&gt;</span><span class="na">getMessage</span><span class="p">();</span>
        <span class="k">echo</span> <span class="s2">&quot;Field: &quot;</span><span class="p">,</span> <span class="nv">$message</span><span class="o">-&gt;</span><span class="na">getField</span><span class="p">();</span>
        <span class="k">echo</span> <span class="s2">&quot;Type: &quot;</span><span class="p">,</span> <span class="nv">$message</span><span class="o">-&gt;</span><span class="na">getType</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p><a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> can generate the following types of validation messages:</p>
<table border="1" class="docutils">
<colgroup>
<col width="14%" />
<col width="86%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Type</th>
<th class="head">Description</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>PresenceOf</td>
<td>Generated when a field with a non-null attribute on the database is trying to insert/update a null value</td>
</tr>
<tr class="row-odd"><td>ConstraintViolation</td>
<td>Generated when a field part of a virtual foreign key is trying to insert/update a value that doesn&#8217;t exist in the referenced model</td>
</tr>
<tr class="row-even"><td>InvalidValue</td>
<td>Generated when a validator failed because of an invalid value</td>
</tr>
<tr class="row-odd"><td>InvalidCreateAttempt</td>
<td>Produced when a record is attempted to be created but it already exists</td>
</tr>
<tr class="row-even"><td>InvalidUpdateAttempt</td>
<td>Produced when a record is attempted to be updated but it doesn&#8217;t exist</td>
</tr>
</tbody>
</table>
<p>The <code class="code docutils literal"><span class="pre">getMessages()</span></code> method can be overridden in a model to replace/translate the default messages generated automatically by the ORM:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">getMessages</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$messages</span> <span class="o">=</span> <span class="p">[];</span>

        <span class="k">foreach</span> <span class="p">(</span><span class="k">parent</span><span class="o">::</span><span class="na">getMessages</span><span class="p">()</span> <span class="k">as</span> <span class="nv">$message</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">switch</span> <span class="p">(</span><span class="nv">$message</span><span class="o">-&gt;</span><span class="na">getType</span><span class="p">())</span> <span class="p">{</span>
                <span class="k">case</span> <span class="s2">&quot;InvalidCreateAttempt&quot;</span><span class="o">:</span>
                    <span class="nv">$messages</span><span class="p">[]</span> <span class="o">=</span> <span class="s2">&quot;The record cannot be created because it already exists&quot;</span><span class="p">;</span>
                    <span class="k">break</span><span class="p">;</span>

                <span class="k">case</span> <span class="s2">&quot;InvalidUpdateAttempt&quot;</span><span class="o">:</span>
                    <span class="nv">$messages</span><span class="p">[]</span> <span class="o">=</span> <span class="s2">&quot;The record cannot be updated because it doesn&#39;t exist&quot;</span><span class="p">;</span>
                    <span class="k">break</span><span class="p">;</span>

                <span class="k">case</span> <span class="s2">&quot;PresenceOf&quot;</span><span class="o">:</span>
                    <span class="nv">$messages</span><span class="p">[]</span> <span class="o">=</span> <span class="s2">&quot;The field &quot;</span> <span class="o">.</span> <span class="nv">$message</span><span class="o">-&gt;</span><span class="na">getField</span><span class="p">()</span> <span class="o">.</span> <span class="s2">&quot; is mandatory&quot;</span><span class="p">;</span>
                    <span class="k">break</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">}</span>

        <span class="k">return</span> <span class="nv">$messages</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="events-and-events-manager">
<h3>事件与事件管理器（Events and Events Manager）<a class="headerlink" href="#events-and-events-manager" title="永久链接至标题">¶</a></h3>
<p>Models allow you to implement events that will be thrown when performing an insert/update/delete. They help define business rules for a
certain model. The following are the events supported by <a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> and their order of execution:</p>
<table border="1" class="docutils">
<colgroup>
<col width="10%" />
<col width="13%" />
<col width="12%" />
<col width="66%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Operation</th>
<th class="head">Name</th>
<th class="head">Can stop operation?</th>
<th class="head">Explanation</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>Inserting/Updating</td>
<td>beforeValidation</td>
<td>YES</td>
<td>Is executed before the fields are validated for not nulls/empty strings or foreign keys</td>
</tr>
<tr class="row-odd"><td>Inserting</td>
<td>beforeValidationOnCreate</td>
<td>YES</td>
<td>Is executed before the fields are validated for not nulls/empty strings or foreign keys when an insertion operation is being made</td>
</tr>
<tr class="row-even"><td>Updating</td>
<td>beforeValidationOnUpdate</td>
<td>YES</td>
<td>Is executed before the fields are validated for not nulls/empty strings or foreign keys when an updating operation is being made</td>
</tr>
<tr class="row-odd"><td>Inserting/Updating</td>
<td>onValidationFails</td>
<td>YES (already stopped)</td>
<td>Is executed after an integrity validator fails</td>
</tr>
<tr class="row-even"><td>Inserting</td>
<td>afterValidationOnCreate</td>
<td>YES</td>
<td>Is executed after the fields are validated for not nulls/empty strings or foreign keys when an insertion operation is being made</td>
</tr>
<tr class="row-odd"><td>Updating</td>
<td>afterValidationOnUpdate</td>
<td>YES</td>
<td>Is executed after the fields are validated for not nulls/empty strings or foreign keys when an updating operation is being made</td>
</tr>
<tr class="row-even"><td>Inserting/Updating</td>
<td>afterValidation</td>
<td>YES</td>
<td>Is executed after the fields are validated for not nulls/empty strings or foreign keys</td>
</tr>
<tr class="row-odd"><td>Inserting/Updating</td>
<td>beforeSave</td>
<td>YES</td>
<td>Runs before the required operation over the database system</td>
</tr>
<tr class="row-even"><td>Updating</td>
<td>beforeUpdate</td>
<td>YES</td>
<td>Runs before the required operation over the database system only when an updating operation is being made</td>
</tr>
<tr class="row-odd"><td>Inserting</td>
<td>beforeCreate</td>
<td>YES</td>
<td>Runs before the required operation over the database system only when an inserting operation is being made</td>
</tr>
<tr class="row-even"><td>Updating</td>
<td>afterUpdate</td>
<td>NO</td>
<td>Runs after the required operation over the database system only when an updating operation is being made</td>
</tr>
<tr class="row-odd"><td>Inserting</td>
<td>afterCreate</td>
<td>NO</td>
<td>Runs after the required operation over the database system only when an inserting operation is being made</td>
</tr>
<tr class="row-even"><td>Inserting/Updating</td>
<td>afterSave</td>
<td>NO</td>
<td>Runs after the required operation over the database system</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="implementing-events-in-the-model-s-class">
<h3>模型中自定义事件（Implementing Events in the Model&#8217;s class）<a class="headerlink" href="#implementing-events-in-the-model-s-class" title="永久链接至标题">¶</a></h3>
<p>The easier way to make a model react to events is implement a method with the same name of the event in the model&#8217;s class:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">beforeValidationOnCreate</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">&quot;This is executed before creating a Robot!&quot;</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Events can be useful to assign values before performing an operation, for example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Products</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">beforeCreate</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="c1">// Set the creation date</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">created_at</span> <span class="o">=</span> <span class="nb">date</span><span class="p">(</span><span class="s2">&quot;Y-m-d H:i:s&quot;</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">beforeUpdate</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="c1">// Set the modification date</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">modified_in</span> <span class="o">=</span> <span class="nb">date</span><span class="p">(</span><span class="s2">&quot;Y-m-d H:i:s&quot;</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="using-a-custom-events-manager">
<h3>使用自定义事件管理器（Using a custom Events Manager）<a class="headerlink" href="#using-a-custom-events-manager" title="永久链接至标题">¶</a></h3>
<p>Additionally, this component is integrated with <a class="reference internal" href="../api/Phalcon_Events_Manager.html"><em>Phalcon\Events\Manager</em></a>,
this means we can create listeners that run when an event is triggered.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Events\Event</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Events\Manager</span> <span class="k">as</span> <span class="nx">EventsManager</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$eventsManager</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventsManager</span><span class="p">();</span>

        <span class="c1">// Attach an anonymous function as a listener for &quot;model&quot; events</span>
        <span class="nv">$eventsManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span>
            <span class="s2">&quot;model:beforeSave&quot;</span><span class="p">,</span>
            <span class="k">function</span> <span class="p">(</span><span class="nx">Event</span> <span class="nv">$event</span><span class="p">,</span> <span class="nv">$robot</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">if</span> <span class="p">(</span><span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">==</span> <span class="s2">&quot;Scooby Doo&quot;</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">echo</span> <span class="s2">&quot;Scooby Doo isn&#39;t a robot!&quot;</span><span class="p">;</span>

                    <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
                <span class="p">}</span>

                <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">);</span>

        <span class="c1">// Attach the events manager to the event</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setEventsManager</span><span class="p">(</span><span class="nv">$eventsManager</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>In the example given above, the Events Manager only acts as a bridge between an object and a listener (the anonymous function).
Events will be fired to the listener when &#8216;robots&#8217; are saved:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Robots</span><span class="p">();</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="s2">&quot;Scooby Doo&quot;</span><span class="p">;</span>
<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">year</span> <span class="o">=</span> <span class="mi">1969</span><span class="p">;</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">save</span><span class="p">();</span>
</pre></div>
</div>
<p>If we want all objects created in our application use the same EventsManager, then we need to assign it to the Models Manager:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Events\Event</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Events\Manager</span> <span class="k">as</span> <span class="nx">EventsManager</span><span class="p">;</span>

<span class="c1">// Registering the modelsManager service</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">setShared</span><span class="p">(</span>
    <span class="s2">&quot;modelsManager&quot;</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="nv">$eventsManager</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventsManager</span><span class="p">();</span>

        <span class="c1">// Attach an anonymous function as a listener for &quot;model&quot; events</span>
        <span class="nv">$eventsManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span>
            <span class="s2">&quot;model:beforeSave&quot;</span><span class="p">,</span>
            <span class="k">function</span> <span class="p">(</span><span class="nx">Event</span> <span class="nv">$event</span><span class="p">,</span> <span class="nv">$model</span><span class="p">)</span> <span class="p">{</span>
                <span class="c1">// Catch events produced by the Robots model</span>
                <span class="k">if</span> <span class="p">(</span><span class="nb">get_class</span><span class="p">(</span><span class="nv">$model</span><span class="p">)</span> <span class="o">===</span> <span class="s2">&quot;Store</span><span class="se">\\</span><span class="s2">Toys</span><span class="se">\\</span><span class="s2">Robots&quot;</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">if</span> <span class="p">(</span><span class="nv">$model</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">===</span> <span class="s2">&quot;Scooby Doo&quot;</span><span class="p">)</span> <span class="p">{</span>
                        <span class="k">echo</span> <span class="s2">&quot;Scooby Doo isn&#39;t a robot!&quot;</span><span class="p">;</span>

                        <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
                    <span class="p">}</span>
                <span class="p">}</span>

                <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">);</span>

        <span class="c1">// Setting a default EventsManager</span>
        <span class="nv">$modelsManager</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ModelsManager</span><span class="p">();</span>

        <span class="nv">$modelsManager</span><span class="o">-&gt;</span><span class="na">setEventsManager</span><span class="p">(</span><span class="nv">$eventsManager</span><span class="p">);</span>

        <span class="k">return</span> <span class="nv">$modelsManager</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">);</span>
</pre></div>
</div>
<p>If a listener returns false that will stop the operation that is executing currently.</p>
</div>
<div class="section" id="implementing-a-business-rule">
<h3>实现业务逻辑（Implementing a Business Rule）<a class="headerlink" href="#implementing-a-business-rule" title="永久链接至标题">¶</a></h3>
<p>When an insert, update or delete is executed, the model verifies if there are any methods with the names of
the events listed in the table above.</p>
<p>We recommend that validation methods are declared protected to prevent that business logic implementation
from being exposed publicly.</p>
<p>The following example implements an event that validates the year cannot be smaller than 0 on update or insert:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">beforeSave</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">year</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">echo</span> <span class="s2">&quot;Year cannot be smaller than zero!&quot;</span><span class="p">;</span>

            <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Some events return false as an indication to stop the current operation. If an event doesn&#8217;t return anything, <a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a>
will assume a true value.</p>
</div>
<div class="section" id="validating-data-integrity">
<h3>验证数据完整性（Validating Data Integrity）<a class="headerlink" href="#validating-data-integrity" title="永久链接至标题">¶</a></h3>
<p><a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> provides several events to validate data and implement business rules. The special &#8220;validation&#8221;
event allows us to call built-in validators over the record. Phalcon exposes a few built-in validators that can be used at this stage of validation.</p>
<p>The following example shows how to use it:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Validation</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Validation\Validator\Uniqueness</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Validation\Validator\InclusionIn</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">validation</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$validator</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Validation</span><span class="p">();</span>

        <span class="nv">$validator</span><span class="o">-&gt;</span><span class="na">validate</span><span class="p">(</span>
            <span class="s2">&quot;type&quot;</span><span class="p">,</span>
            <span class="k">new</span> <span class="nx">InclusionIn</span><span class="p">(</span>
                <span class="p">[</span>
                    <span class="s2">&quot;domain&quot;</span> <span class="o">=&gt;</span> <span class="p">[</span>
                        <span class="s2">&quot;Mechanical&quot;</span><span class="p">,</span>
                        <span class="s2">&quot;Virtual&quot;</span><span class="p">,</span>
                    <span class="p">]</span>
                <span class="p">]</span>
            <span class="p">)</span>
        <span class="p">);</span>

        <span class="nv">$validator</span><span class="o">-&gt;</span><span class="na">validate</span><span class="p">(</span>
            <span class="s2">&quot;name&quot;</span><span class="p">,</span>
            <span class="k">new</span> <span class="nx">Uniqueness</span><span class="p">(</span>
                <span class="p">[</span>
                    <span class="s2">&quot;message&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;The robot name must be unique&quot;</span><span class="p">,</span>
                <span class="p">]</span>
            <span class="p">)</span>
        <span class="p">);</span>

        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">validate</span><span class="p">(</span><span class="nv">$validator</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The above example performs a validation using the built-in validator &#8220;InclusionIn&#8221;. It checks the value of the field &#8220;type&#8221; in a domain list. If
the value is not included in the method then the validator will fail and return false. The following built-in validators are available:</p>
<blockquote class="highlights">
<div>For more information on validators, see the <a class="reference internal" href="validation.html"><em>Validation documentation</em></a>.</div></blockquote>
<p>The idea of creating validators is make them reusable between several models. A validator can also be as simple as:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model\Message</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">validation</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">type</span> <span class="o">===</span> <span class="s2">&quot;Old&quot;</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$message</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Message</span><span class="p">(</span>
                <span class="s2">&quot;Sorry, old robots are not allowed anymore&quot;</span><span class="p">,</span>
                <span class="s2">&quot;type&quot;</span><span class="p">,</span>
                <span class="s2">&quot;MyType&quot;</span>
            <span class="p">);</span>

            <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">appendMessage</span><span class="p">(</span><span class="nv">$message</span><span class="p">);</span>

            <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="skipping-columns">
<h2>忽略指定列的数据（Skipping Columns）<a class="headerlink" href="#skipping-columns" title="永久链接至标题">¶</a></h2>
<p>To tell <a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> that always omits some fields in the creation and/or update of records in order
to delegate the database system the assignation of the values by a trigger or a default:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="c1">// Skips fields/columns on both INSERT/UPDATE operations</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">skipAttributes</span><span class="p">(</span>
            <span class="p">[</span>
                <span class="s2">&quot;year&quot;</span><span class="p">,</span>
                <span class="s2">&quot;price&quot;</span><span class="p">,</span>
            <span class="p">]</span>
        <span class="p">);</span>

        <span class="c1">// Skips only when inserting</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">skipAttributesOnCreate</span><span class="p">(</span>
            <span class="p">[</span>
                <span class="s2">&quot;created_at&quot;</span><span class="p">,</span>
            <span class="p">]</span>
        <span class="p">);</span>

        <span class="c1">// Skips only when updating</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">skipAttributesOnUpdate</span><span class="p">(</span>
            <span class="p">[</span>
                <span class="s2">&quot;modified_in&quot;</span><span class="p">,</span>
            <span class="p">]</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>This will ignore globally these fields on each INSERT/UPDATE operation on the whole application.
If you want to ignore different attributes on different INSERT/UPDATE operations, you can specify the second parameter (boolean) - true
for replacement. Forcing a default value can be done in the following way:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Db\RawValue</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Robots</span><span class="p">();</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span>       <span class="o">=</span> <span class="s2">&quot;Bender&quot;</span><span class="p">;</span>
<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">year</span>       <span class="o">=</span> <span class="mi">1999</span><span class="p">;</span>
<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">created_at</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">RawValue</span><span class="p">(</span><span class="s2">&quot;default&quot;</span><span class="p">);</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">create</span><span class="p">();</span>
</pre></div>
</div>
<p>A callback also can be used to create a conditional assignment of automatic default values:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Db\RawValue</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">beforeCreate</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">price</span> <span class="o">&gt;</span> <span class="mi">10000</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">type</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">RawValue</span><span class="p">(</span><span class="s2">&quot;default&quot;</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<blockquote class="highlights">
<div>Never use a <a class="reference internal" href="../api/Phalcon_Db_RawValue.html"><em>Phalcon\Db\RawValue</em></a> to assign external data (such as user input)
or variable data. The value of these fields is ignored when binding parameters to the query.
So it could be used to attack the application injecting SQL.</div></blockquote>
<div class="section" id="dynamic-update">
<h3>动态更新（Dynamic Update）<a class="headerlink" href="#dynamic-update" title="永久链接至标题">¶</a></h3>
<p>SQL UPDATE statements are by default created with every column defined in the model (full all-field SQL update).
You can change specific models to make dynamic updates, in this case, just the fields that had changed
are used to create the final SQL statement.</p>
<p>In some cases this could improve the performance by reducing the traffic between the application and the database server,
this specially helps when the table has blob/text fields:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">useDynamicUpdate</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="deleting-records">
<h2>删除记录（Deleting Records）<a class="headerlink" href="#deleting-records" title="永久链接至标题">¶</a></h2>
<p>The <code class="code docutils literal"><span class="pre">Phalcon\Mvc\Model::delete()</span></code> method allows to delete a record. You can use it as follows:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span><span class="mi">11</span><span class="p">);</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$robot</span> <span class="o">!==</span> <span class="k">false</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">delete</span><span class="p">()</span> <span class="o">===</span> <span class="k">false</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">&quot;Sorry, we can&#39;t delete the robot right now: </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>

        <span class="nv">$messages</span> <span class="o">=</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">getMessages</span><span class="p">();</span>

        <span class="k">foreach</span> <span class="p">(</span><span class="nv">$messages</span> <span class="k">as</span> <span class="nv">$message</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">echo</span> <span class="nv">$message</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">&quot;The robot was deleted successfully!&quot;</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>You can also delete many records by traversing a resultset with a foreach:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robots</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="s2">&quot;type = &#39;mechanical&#39;&quot;</span>
<span class="p">);</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$robots</span> <span class="k">as</span> <span class="nv">$robot</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">delete</span><span class="p">()</span> <span class="o">===</span> <span class="k">false</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">&quot;Sorry, we can&#39;t delete the robot right now: </span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>

        <span class="nv">$messages</span> <span class="o">=</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">getMessages</span><span class="p">();</span>

        <span class="k">foreach</span> <span class="p">(</span><span class="nv">$messages</span> <span class="k">as</span> <span class="nv">$message</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">echo</span> <span class="nv">$message</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">&quot;The robot was deleted successfully!&quot;</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The following events are available to define custom business rules that can be executed when a delete operation is
performed:</p>
<table border="1" class="docutils">
<colgroup>
<col width="13%" />
<col width="16%" />
<col width="24%" />
<col width="48%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Operation</th>
<th class="head">Name</th>
<th class="head">Can stop operation?</th>
<th class="head">Explanation</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>Deleting</td>
<td>beforeDelete</td>
<td>YES</td>
<td>Runs before the delete operation is made</td>
</tr>
<tr class="row-odd"><td>Deleting</td>
<td>afterDelete</td>
<td>NO</td>
<td>Runs after the delete operation was made</td>
</tr>
</tbody>
</table>
<p>With the above events can also define business rules in the models:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">beforeDelete</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">status</span> <span class="o">==</span> <span class="s2">&quot;A&quot;</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">echo</span> <span class="s2">&quot;The robot is active, it can&#39;t be deleted&quot;</span><span class="p">;</span>

            <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="validation-failed-events">
<h2>验证失败事件（Validation Failed Events）<a class="headerlink" href="#validation-failed-events" title="永久链接至标题">¶</a></h2>
<p>Another type of events are available when the data validation process finds any inconsistency:</p>
<table border="1" class="docutils">
<colgroup>
<col width="23%" />
<col width="18%" />
<col width="60%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Operation</th>
<th class="head">Name</th>
<th class="head">Explanation</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>Insert or Update</td>
<td>notSaved</td>
<td>Triggered when the INSERT or UPDATE operation fails for any reason</td>
</tr>
<tr class="row-odd"><td>Insert, Delete or Update</td>
<td>onValidationFails</td>
<td>Triggered when any data manipulation operation fails</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="independent-column-mapping">
<h2>独立的列映射（Independent Column Mapping）<a class="headerlink" href="#independent-column-mapping" title="永久链接至标题">¶</a></h2>
<p>The ORM supports an independent column map, which allows the developer to use different column names in the model to the ones in
the table. Phalcon will recognize the new column names and will rename them accordingly to match the respective columns in the database.
This is a great feature when one needs to rename fields in the database without having to worry about all the queries
in the code. A change in the column map in the model will take care of the rest. For example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="nv">$code</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$theName</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$theType</span><span class="p">;</span>

    <span class="k">public</span> <span class="nv">$theYear</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">columnMap</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="c1">// Keys are the real names in the table and</span>
        <span class="c1">// the values their names in the application</span>
        <span class="k">return</span> <span class="p">[</span>
            <span class="s2">&quot;id&quot;</span>       <span class="o">=&gt;</span> <span class="s2">&quot;code&quot;</span><span class="p">,</span>
            <span class="s2">&quot;the_name&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;theName&quot;</span><span class="p">,</span>
            <span class="s2">&quot;the_type&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;theType&quot;</span><span class="p">,</span>
            <span class="s2">&quot;the_year&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;theYear&quot;</span><span class="p">,</span>
        <span class="p">];</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Then you can use the new names naturally in your code:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="c1">// Find a robot by its name</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span>
    <span class="s2">&quot;theName = &#39;Voltron&#39;&quot;</span>
<span class="p">);</span>

<span class="k">echo</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">theName</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>

<span class="c1">// Get robots ordered by type</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;order&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;theType DESC&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$robots</span> <span class="k">as</span> <span class="nv">$robot</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s2">&quot;Code: &quot;</span><span class="p">,</span> <span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">code</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// Create a robot</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Robots</span><span class="p">();</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">code</span>    <span class="o">=</span> <span class="s2">&quot;10101&quot;</span><span class="p">;</span>
<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">theName</span> <span class="o">=</span> <span class="s2">&quot;Bender&quot;</span><span class="p">;</span>
<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">theType</span> <span class="o">=</span> <span class="s2">&quot;Industrial&quot;</span><span class="p">;</span>
<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">theYear</span> <span class="o">=</span> <span class="mi">2999</span><span class="p">;</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">save</span><span class="p">();</span>
</pre></div>
</div>
<p>Take into consideration the following the next when renaming your columns:</p>
<ul class="simple">
<li>References to attributes in relationships/validators must use the new names</li>
<li>Refer the real column names will result in an exception by the ORM</li>
</ul>
<p>The independent column map allow you to:</p>
<ul class="simple">
<li>Write applications using your own conventions</li>
<li>Eliminate vendor prefixes/suffixes in your code</li>
<li>Change column names without change your application code</li>
</ul>
</div>
<div class="section" id="operations-over-resultsets">
<h2>在结果集中操作（Operations over Resultsets）<a class="headerlink" href="#operations-over-resultsets" title="永久链接至标题">¶</a></h2>
<p>If a resultset is composed of complete objects, the resultset is in the ability to perform operations on the records obtained in a simple manner:</p>
<div class="section" id="updating-related-records">
<h3>更新关联表记录（Updating related records）<a class="headerlink" href="#updating-related-records" title="永久链接至标题">¶</a></h3>
<p>Instead of doing this:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$parts</span> <span class="o">=</span> <span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">getParts</span><span class="p">();</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$parts</span> <span class="k">as</span> <span class="nv">$part</span><span class="p">)</span> <span class="p">{</span>
    <span class="nv">$part</span><span class="o">-&gt;</span><span class="na">stock</span>      <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>
    <span class="nv">$part</span><span class="o">-&gt;</span><span class="na">updated_at</span> <span class="o">=</span> <span class="nb">time</span><span class="p">();</span>

    <span class="k">if</span> <span class="p">(</span><span class="nv">$part</span><span class="o">-&gt;</span><span class="na">update</span><span class="p">()</span> <span class="o">===</span> <span class="k">false</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$messages</span> <span class="o">=</span> <span class="nv">$part</span><span class="o">-&gt;</span><span class="na">getMessages</span><span class="p">();</span>

        <span class="k">foreach</span> <span class="p">(</span><span class="nv">$messages</span> <span class="k">as</span> <span class="nv">$message</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">echo</span> <span class="nv">$message</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="k">break</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>you can do this:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">getParts</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">update</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;stock&quot;</span>      <span class="o">=&gt;</span> <span class="mi">100</span><span class="p">,</span>
        <span class="s2">&quot;updated_at&quot;</span> <span class="o">=&gt;</span> <span class="nb">time</span><span class="p">(),</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<p>&#8216;update&#8217; also accepts an anonymous function to filter what records must be updated:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$data</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s2">&quot;stock&quot;</span>      <span class="o">=&gt;</span> <span class="mi">100</span><span class="p">,</span>
    <span class="s2">&quot;updated_at&quot;</span> <span class="o">=&gt;</span> <span class="nb">time</span><span class="p">(),</span>
<span class="p">];</span>

<span class="c1">// Update all the parts except those whose type is basic</span>
<span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">getParts</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">update</span><span class="p">(</span>
    <span class="nv">$data</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">(</span><span class="nv">$part</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nv">$part</span><span class="o">-&gt;</span><span class="na">type</span> <span class="o">===</span> <span class="nx">Part</span><span class="o">::</span><span class="na">TYPE_BASIC</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="deleting-related-records">
<h3>删除关联表记录（Deleting related records）<a class="headerlink" href="#deleting-related-records" title="永久链接至标题">¶</a></h3>
<p>Instead of doing this:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$parts</span> <span class="o">=</span> <span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">getParts</span><span class="p">();</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$parts</span> <span class="k">as</span> <span class="nv">$part</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nv">$part</span><span class="o">-&gt;</span><span class="na">delete</span><span class="p">()</span> <span class="o">===</span> <span class="k">false</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$messages</span> <span class="o">=</span> <span class="nv">$part</span><span class="o">-&gt;</span><span class="na">getMessages</span><span class="p">();</span>

        <span class="k">foreach</span> <span class="p">(</span><span class="nv">$messages</span> <span class="k">as</span> <span class="nv">$message</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">echo</span> <span class="nv">$message</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="k">break</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>you can do this:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">getParts</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">delete</span><span class="p">();</span>
</pre></div>
</div>
<p><code class="code docutils literal"><span class="pre">delete()</span></code> also accepts an anonymous function to filter what records must be deleted:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">// Delete only whose stock is greater or equal than zero</span>
<span class="nv">$robots</span><span class="o">-&gt;</span><span class="na">getParts</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">delete</span><span class="p">(</span>
    <span class="k">function</span> <span class="p">(</span><span class="nv">$part</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="nv">$part</span><span class="o">-&gt;</span><span class="na">stock</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="k">false</span><span class="p">;</span>
        <span class="p">}</span>

        <span class="k">return</span> <span class="k">true</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">);</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="record-snapshots">
<h2>记录快照（Record Snapshots）<a class="headerlink" href="#record-snapshots" title="永久链接至标题">¶</a></h2>
<p>Specific models could be set to maintain a record snapshot when they&#8217;re queried. You can use this feature to implement auditing or just to know what
fields are changed according to the data queried from the persistence:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">keepSnapshots</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>When activating this feature the application consumes a bit more of memory to keep track of the original values obtained from the persistence.
In models that have this feature activated you can check what fields changed:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="c1">// Get a record from the database</span>
<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">();</span>

<span class="c1">// Change a column</span>
<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="s2">&quot;Other name&quot;</span><span class="p">;</span>

<span class="nb">var_dump</span><span class="p">(</span><span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">getChangedFields</span><span class="p">());</span> <span class="c1">// [&quot;name&quot;]</span>

<span class="nb">var_dump</span><span class="p">(</span><span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">hasChanged</span><span class="p">(</span><span class="s2">&quot;name&quot;</span><span class="p">));</span> <span class="c1">// true</span>

<span class="nb">var_dump</span><span class="p">(</span><span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">hasChanged</span><span class="p">(</span><span class="s2">&quot;type&quot;</span><span class="p">));</span> <span class="c1">// false</span>
</pre></div>
</div>
</div>
<div class="section" id="pointing-to-a-different-schema">
<h2>设置模式（Pointing to a different schema）<a class="headerlink" href="#pointing-to-a-different-schema" title="永久链接至标题">¶</a></h2>
<p>如果一个模型映射到一个在非默认的schemas/数据库中的表，你可以通过 <code class="code docutils literal"><span class="pre">setSchema()</span></code> 方法去定义它：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setSchema</span><span class="p">(</span><span class="s2">&quot;toys&quot;</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="setting-multiple-databases">
<h2>设置多个数据库（Setting multiple databases）<a class="headerlink" href="#setting-multiple-databases" title="永久链接至标题">¶</a></h2>
<p>在Phalcon中，所有模型可以属于同一个数据库连接，也可以分属独立的数据库连接。实际上，当 <a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a>
需要连接数据库的时候，它在应用服务容器内请求&#8221;db&#8221;这个服务。 可以通过在 <code class="code docutils literal"><span class="pre">initialize()</span></code> 方法内重写这个服务的设置。</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Db\Adapter\Pdo\Mysql</span> <span class="k">as</span> <span class="nx">MysqlPdo</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Db\Adapter\Pdo\PostgreSQL</span> <span class="k">as</span> <span class="nx">PostgreSQLPdo</span><span class="p">;</span>

<span class="c1">// This service returns a MySQL database</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;dbMysql&quot;</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nx">MysqlPdo</span><span class="p">(</span>
            <span class="p">[</span>
                <span class="s2">&quot;host&quot;</span>     <span class="o">=&gt;</span> <span class="s2">&quot;localhost&quot;</span><span class="p">,</span>
                <span class="s2">&quot;username&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;root&quot;</span><span class="p">,</span>
                <span class="s2">&quot;password&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;secret&quot;</span><span class="p">,</span>
                <span class="s2">&quot;dbname&quot;</span>   <span class="o">=&gt;</span> <span class="s2">&quot;invo&quot;</span><span class="p">,</span>
            <span class="p">]</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">);</span>

<span class="c1">// This service returns a PostgreSQL database</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;dbPostgres&quot;</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nx">PostgreSQLPdo</span><span class="p">(</span>
            <span class="p">[</span>
                <span class="s2">&quot;host&quot;</span>     <span class="o">=&gt;</span> <span class="s2">&quot;localhost&quot;</span><span class="p">,</span>
                <span class="s2">&quot;username&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;postgres&quot;</span><span class="p">,</span>
                <span class="s2">&quot;password&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
                <span class="s2">&quot;dbname&quot;</span>   <span class="o">=&gt;</span> <span class="s2">&quot;invo&quot;</span><span class="p">,</span>
            <span class="p">]</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">);</span>
</pre></div>
</div>
<p>然后，在 <code class="code docutils literal"><span class="pre">initialize()</span></code> 方法内，我们为这个模型定义数据库连接。</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setConnectionService</span><span class="p">(</span><span class="s2">&quot;dbPostgres&quot;</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>另外Phalcon还提供了更多的灵活性，你可分别定义用来读取和写入的数据库连接。这对实现主从架构的数据库负载均衡非常有用。
（译者注：EvaEngine项目为使用Phalcon提供了更多的灵活性，推荐了解和使用）</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">initialize</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setReadConnectionService</span><span class="p">(</span><span class="s2">&quot;dbSlave&quot;</span><span class="p">);</span>

        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">setWriteConnectionService</span><span class="p">(</span><span class="s2">&quot;dbMaster&quot;</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>另外ORM还可以通过根据当前查询条件来实现一个 &#8216;shard&#8217; 选择器，来实现水平切分的功能。</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="sd">/**</span>
<span class="sd">     * Dynamically selects a shard</span>
<span class="sd">     *</span>
<span class="sd">     * @param array $intermediate</span>
<span class="sd">     * @param array $bindParams</span>
<span class="sd">     * @param array $bindTypes</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">selectReadConnection</span><span class="p">(</span><span class="nv">$intermediate</span><span class="p">,</span> <span class="nv">$bindParams</span><span class="p">,</span> <span class="nv">$bindTypes</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="c1">// Check if there is a &#39;where&#39; clause in the select</span>
        <span class="k">if</span> <span class="p">(</span><span class="nb">isset</span><span class="p">(</span><span class="nv">$intermediate</span><span class="p">[</span><span class="s2">&quot;where&quot;</span><span class="p">]))</span> <span class="p">{</span>
            <span class="nv">$conditions</span> <span class="o">=</span> <span class="nv">$intermediate</span><span class="p">[</span><span class="s2">&quot;where&quot;</span><span class="p">];</span>

            <span class="c1">// Choose the possible shard according to the conditions</span>
            <span class="k">if</span> <span class="p">(</span><span class="nv">$conditions</span><span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">][</span><span class="s2">&quot;name&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;id&quot;</span><span class="p">)</span> <span class="p">{</span>
                <span class="nv">$id</span> <span class="o">=</span> <span class="nv">$conditions</span><span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">][</span><span class="s2">&quot;value&quot;</span><span class="p">];</span>

                <span class="k">if</span> <span class="p">(</span><span class="nv">$id</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="nv">$id</span> <span class="o">&lt;</span> <span class="mi">10000</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getDI</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s2">&quot;dbShard1&quot;</span><span class="p">);</span>
                <span class="p">}</span>

                <span class="k">if</span> <span class="p">(</span><span class="nv">$id</span> <span class="o">&gt;</span> <span class="mi">10000</span><span class="p">)</span> <span class="p">{</span>
                    <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getDI</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s2">&quot;dbShard2&quot;</span><span class="p">);</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">}</span>

        <span class="c1">// Use a default shard</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getDI</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s2">&quot;dbShard0&quot;</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p><code class="code docutils literal"><span class="pre">selectReadConnection()</span></code> 方法用来选择正确的数据库连接，这个方法拦截任何新的查询操作：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">findFirst</span><span class="p">(</span><span class="s1">&#39;id = 101&#39;</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="sql-logging-low-level-sql-statements">
<h2>记录底层 SQL 语句（Logging Low-Level SQL Statements）<a class="headerlink" href="#sql-logging-low-level-sql-statements" title="永久链接至标题">¶</a></h2>
<p>When using high-level abstraction components such as <a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a> to access a database, it is
difficult to understand which statements are finally sent to the database system. <a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a>
is supported internally by <a class="reference internal" href="../api/Phalcon_Db.html"><em>Phalcon\Db</em></a>. <a class="reference internal" href="../api/Phalcon_Logger.html"><em>Phalcon\Logger</em></a> interacts
with <a class="reference internal" href="../api/Phalcon_Db.html"><em>Phalcon\Db</em></a>, providing logging capabilities on the database abstraction layer, thus allowing us to log SQL
statements as they happen.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Logger</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Events\Manager</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Logger\Adapter\File</span> <span class="k">as</span> <span class="nx">FileLogger</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Db\Adapter\Pdo\Mysql</span> <span class="k">as</span> <span class="nx">Connection</span><span class="p">;</span>

<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;db&quot;</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="nv">$eventsManager</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventsManager</span><span class="p">();</span>

        <span class="nv">$logger</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">FileLogger</span><span class="p">(</span><span class="s2">&quot;app/logs/debug.log&quot;</span><span class="p">);</span>

        <span class="c1">// Listen all the database events</span>
        <span class="nv">$eventsManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span>
            <span class="s2">&quot;db:beforeQuery&quot;</span><span class="p">,</span>
            <span class="k">function</span> <span class="p">(</span><span class="nv">$event</span><span class="p">,</span> <span class="nv">$connection</span><span class="p">)</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$logger</span><span class="p">)</span> <span class="p">{</span>
                <span class="nv">$logger</span><span class="o">-&gt;</span><span class="na">log</span><span class="p">(</span>
                    <span class="nv">$connection</span><span class="o">-&gt;</span><span class="na">getSQLStatement</span><span class="p">(),</span>
                    <span class="nx">Logger</span><span class="o">::</span><span class="na">INFO</span>
                <span class="p">);</span>
            <span class="p">}</span>
        <span class="p">);</span>

        <span class="nv">$connection</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Connection</span><span class="p">(</span>
            <span class="p">[</span>
                <span class="s2">&quot;host&quot;</span>     <span class="o">=&gt;</span> <span class="s2">&quot;localhost&quot;</span><span class="p">,</span>
                <span class="s2">&quot;username&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;root&quot;</span><span class="p">,</span>
                <span class="s2">&quot;password&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;secret&quot;</span><span class="p">,</span>
                <span class="s2">&quot;dbname&quot;</span>   <span class="o">=&gt;</span> <span class="s2">&quot;invo&quot;</span><span class="p">,</span>
            <span class="p">]</span>
        <span class="p">);</span>

        <span class="c1">// Assign the eventsManager to the db adapter instance</span>
        <span class="nv">$connection</span><span class="o">-&gt;</span><span class="na">setEventsManager</span><span class="p">(</span><span class="nv">$eventsManager</span><span class="p">);</span>

        <span class="k">return</span> <span class="nv">$connection</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">);</span>
</pre></div>
</div>
<p>As models access the default database connection, all SQL statements that are sent to the database system will be logged in the file:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="nv">$robot</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Robots</span><span class="p">();</span>

<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">name</span>       <span class="o">=</span> <span class="s2">&quot;Robby the Robot&quot;</span><span class="p">;</span>
<span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">created_at</span> <span class="o">=</span> <span class="s2">&quot;1956-07-21&quot;</span><span class="p">;</span>

<span class="k">if</span> <span class="p">(</span><span class="nv">$robot</span><span class="o">-&gt;</span><span class="na">save</span><span class="p">()</span> <span class="o">===</span> <span class="k">false</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s2">&quot;Cannot save robot&quot;</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>As above, the file <em>app/logs/db.log</em> will contain something like this:</p>
<div class="highlight-irc"><div class="highlight"><pre>[Mon, 30 Apr 12 13:47:18 -0500][DEBUG][Resource Id #77] INSERT INTO robots
(name, created_at) VALUES (&#39;Robby the Robot&#39;, &#39;1956-07-21&#39;)
</pre></div>
</div>
</div>
<div class="section" id="sql-profiling-sql-statements">
<h2>分析 SQL 语句（Profiling SQL Statements）<a class="headerlink" href="#sql-profiling-sql-statements" title="永久链接至标题">¶</a></h2>
<p>Thanks to <a class="reference internal" href="../api/Phalcon_Db.html"><em>Phalcon\Db</em></a>, the underlying component of <a class="reference internal" href="../api/Phalcon_Mvc_Model.html"><em>Phalcon\Mvc\Model</em></a>,
it&#8217;s possible to profile the SQL statements generated by the ORM in order to analyze the performance of database operations. With
this you can diagnose performance problems and to discover bottlenecks.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Db\Profiler</span> <span class="k">as</span> <span class="nx">ProfilerDb</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Events\Manager</span> <span class="k">as</span> <span class="nx">EventsManager</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Db\Adapter\Pdo\Mysql</span> <span class="k">as</span> <span class="nx">MysqlPdo</span><span class="p">;</span>

<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;profiler&quot;</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nx">ProfilerDb</span><span class="p">();</span>
    <span class="p">},</span>
    <span class="k">true</span>
<span class="p">);</span>

<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;db&quot;</span><span class="p">,</span>
    <span class="k">function</span> <span class="p">()</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$di</span><span class="p">)</span> <span class="p">{</span>
        <span class="nv">$eventsManager</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventsManager</span><span class="p">();</span>

        <span class="c1">// Get a shared instance of the DbProfiler</span>
        <span class="nv">$profiler</span> <span class="o">=</span> <span class="nv">$di</span><span class="o">-&gt;</span><span class="na">getProfiler</span><span class="p">();</span>

        <span class="c1">// Listen all the database events</span>
        <span class="nv">$eventsManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span>
            <span class="s2">&quot;db&quot;</span><span class="p">,</span>
            <span class="k">function</span> <span class="p">(</span><span class="nv">$event</span><span class="p">,</span> <span class="nv">$connection</span><span class="p">)</span> <span class="k">use</span> <span class="p">(</span><span class="nv">$profiler</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">if</span> <span class="p">(</span><span class="nv">$event</span><span class="o">-&gt;</span><span class="na">getType</span><span class="p">()</span> <span class="o">===</span> <span class="s2">&quot;beforeQuery&quot;</span><span class="p">)</span> <span class="p">{</span>
                    <span class="nv">$profiler</span><span class="o">-&gt;</span><span class="na">startProfile</span><span class="p">(</span>
                        <span class="nv">$connection</span><span class="o">-&gt;</span><span class="na">getSQLStatement</span><span class="p">()</span>
                    <span class="p">);</span>
                <span class="p">}</span>

                <span class="k">if</span> <span class="p">(</span><span class="nv">$event</span><span class="o">-&gt;</span><span class="na">getType</span><span class="p">()</span> <span class="o">===</span> <span class="s2">&quot;afterQuery&quot;</span><span class="p">)</span> <span class="p">{</span>
                    <span class="nv">$profiler</span><span class="o">-&gt;</span><span class="na">stopProfile</span><span class="p">();</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">);</span>

        <span class="nv">$connection</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MysqlPdo</span><span class="p">(</span>
            <span class="p">[</span>
                <span class="s2">&quot;host&quot;</span>     <span class="o">=&gt;</span> <span class="s2">&quot;localhost&quot;</span><span class="p">,</span>
                <span class="s2">&quot;username&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;root&quot;</span><span class="p">,</span>
                <span class="s2">&quot;password&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;secret&quot;</span><span class="p">,</span>
                <span class="s2">&quot;dbname&quot;</span>   <span class="o">=&gt;</span> <span class="s2">&quot;invo&quot;</span><span class="p">,</span>
            <span class="p">]</span>
        <span class="p">);</span>

        <span class="c1">// Assign the eventsManager to the db adapter instance</span>
        <span class="nv">$connection</span><span class="o">-&gt;</span><span class="na">setEventsManager</span><span class="p">(</span><span class="nv">$eventsManager</span><span class="p">);</span>

        <span class="k">return</span> <span class="nv">$connection</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">);</span>
</pre></div>
</div>
<p>Profiling some queries:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Store\Toys\Robots</span><span class="p">;</span>

<span class="c1">// Send some SQL statements to the database</span>
<span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">();</span>

<span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;order&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;name&quot;</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="nx">Robots</span><span class="o">::</span><span class="na">find</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;limit&quot;</span> <span class="o">=&gt;</span> <span class="mi">30</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>

<span class="c1">// Get the generated profiles from the profiler</span>
<span class="nv">$profiles</span> <span class="o">=</span> <span class="nv">$di</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s2">&quot;profiler&quot;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">getProfiles</span><span class="p">();</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$profiles</span> <span class="k">as</span> <span class="nv">$profile</span><span class="p">)</span> <span class="p">{</span>
   <span class="k">echo</span> <span class="s2">&quot;SQL Statement: &quot;</span><span class="p">,</span> <span class="nv">$profile</span><span class="o">-&gt;</span><span class="na">getSQLStatement</span><span class="p">(),</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
   <span class="k">echo</span> <span class="s2">&quot;Start Time: &quot;</span><span class="p">,</span> <span class="nv">$profile</span><span class="o">-&gt;</span><span class="na">getInitialTime</span><span class="p">(),</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
   <span class="k">echo</span> <span class="s2">&quot;Final Time: &quot;</span><span class="p">,</span> <span class="nv">$profile</span><span class="o">-&gt;</span><span class="na">getFinalTime</span><span class="p">(),</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
   <span class="k">echo</span> <span class="s2">&quot;Total Elapsed Time: &quot;</span><span class="p">,</span> <span class="nv">$profile</span><span class="o">-&gt;</span><span class="na">getTotalElapsedSeconds</span><span class="p">(),</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Each generated profile contains the duration in milliseconds that each instruction takes to complete as well as the generated SQL statement.</p>
</div>
<div class="section" id="injecting-services-into-models">
<h2>注入服务到模型（Injecting services into Models）<a class="headerlink" href="#injecting-services-into-models" title="永久链接至标题">¶</a></h2>
<p>你可能需要在模型中用到应用中注入的服务，下面的例子会教你如何去做：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">namespace</span> <span class="nx">Store\Toys</span><span class="p">;</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">notSaved</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="c1">// Obtain the flash service from the DI container</span>
        <span class="nv">$flash</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getDI</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getFlash</span><span class="p">();</span>

        <span class="nv">$messages</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getMessages</span><span class="p">();</span>

        <span class="c1">// Show validation messages</span>
        <span class="k">foreach</span> <span class="p">(</span><span class="nv">$messages</span> <span class="k">as</span> <span class="nv">$message</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$flash</span><span class="o">-&gt;</span><span class="na">error</span><span class="p">(</span><span class="nv">$message</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>每当 &#8220;create&#8221; 或者 &#8220;update&#8221; 操作失败时会触发 &#8220;notSave&#8221; 事件。所以我们从DI中获取 &#8220;flash&#8221; 服务并推送确认消息。这样的话，我们不需要每次在save之后去打印信息。</p>
</div>
<div class="section" id="disabling-enabling-features">
<h2>禁用或启用特性（Disabling/Enabling Features）<a class="headerlink" href="#disabling-enabling-features" title="永久链接至标题">¶</a></h2>
<p>In the ORM we have implemented a mechanism that allow you to enable/disable specific features or options globally on the fly.
According to how you use the ORM you can disable that you aren&#8217;t using. These options can also be temporarily disabled if required:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>

<span class="nx">Model</span><span class="o">::</span><span class="na">setup</span><span class="p">(</span>
    <span class="p">[</span>
        <span class="s2">&quot;events&quot;</span>         <span class="o">=&gt;</span> <span class="k">false</span><span class="p">,</span>
        <span class="s2">&quot;columnRenaming&quot;</span> <span class="o">=&gt;</span> <span class="k">false</span><span class="p">,</span>
    <span class="p">]</span>
<span class="p">);</span>
</pre></div>
</div>
<p>The available options are:</p>
<table border="1" class="docutils">
<colgroup>
<col width="17%" />
<col width="71%" />
<col width="12%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Option</th>
<th class="head">Description</th>
<th class="head">Default</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>events</td>
<td>Enables/Disables callbacks, hooks and event notifications from all the models</td>
<td><code class="code docutils literal"><span class="pre">true</span></code></td>
</tr>
<tr class="row-odd"><td>columnRenaming</td>
<td>Enables/Disables the column renaming</td>
<td><code class="code docutils literal"><span class="pre">true</span></code></td>
</tr>
<tr class="row-even"><td>notNullValidations</td>
<td>The ORM automatically validate the not null columns present in the mapped table</td>
<td><code class="code docutils literal"><span class="pre">true</span></code></td>
</tr>
<tr class="row-odd"><td>virtualForeignKeys</td>
<td>Enables/Disables the virtual foreign keys</td>
<td><code class="code docutils literal"><span class="pre">true</span></code></td>
</tr>
<tr class="row-even"><td>phqlLiterals</td>
<td>Enables/Disables literals in the PHQL parser</td>
<td><code class="code docutils literal"><span class="pre">true</span></code></td>
</tr>
<tr class="row-odd"><td>lateStateBinding</td>
<td>Enables/Disables late state binding of the <code class="code docutils literal"><span class="pre">Mvc\Model::cloneResultMap()</span></code> method</td>
<td><code class="code docutils literal"><span class="pre">false</span></code></td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="stand-alone-component">
<h2>独立的组件（Stand-Alone component）<a class="headerlink" href="#stand-alone-component" title="永久链接至标题">¶</a></h2>
<p>Using <a class="reference internal" href=""><em>Phalcon\Mvc\Model</em></a> in a stand-alone mode can be demonstrated below:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Di</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model\Manager</span> <span class="k">as</span> <span class="nx">ModelsManager</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Db\Adapter\Pdo\Sqlite</span> <span class="k">as</span> <span class="nx">Connection</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Phalcon\Mvc\Model\Metadata\Memory</span> <span class="k">as</span> <span class="nx">MetaData</span><span class="p">;</span>

<span class="nv">$di</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Di</span><span class="p">();</span>

<span class="c1">// Setup a connection</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;db&quot;</span><span class="p">,</span>
    <span class="k">new</span> <span class="nx">Connection</span><span class="p">(</span>
        <span class="p">[</span>
            <span class="s2">&quot;dbname&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;sample.db&quot;</span><span class="p">,</span>
        <span class="p">]</span>
    <span class="p">)</span>
<span class="p">);</span>

<span class="c1">// Set a models manager</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;modelsManager&quot;</span><span class="p">,</span>
    <span class="k">new</span> <span class="nx">ModelsManager</span><span class="p">()</span>
<span class="p">);</span>

<span class="c1">// Use the memory meta-data adapter or other</span>
<span class="nv">$di</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span>
    <span class="s2">&quot;modelsMetadata&quot;</span><span class="p">,</span>
    <span class="k">new</span> <span class="nx">MetaData</span><span class="p">()</span>
<span class="p">);</span>

<span class="c1">// Create a model</span>
<span class="k">class</span> <span class="nc">Robots</span> <span class="k">extends</span> <span class="nx">Model</span>
<span class="p">{</span>

<span class="p">}</span>

<span class="c1">// Use the model</span>
<span class="k">echo</span> <span class="nx">Robots</span><span class="o">::</span><span class="na">count</span><span class="p">();</span>
</pre></div>
</div>
</div>
</div>


                    </div>
                  </div>
                </div>
            </div>
          </td>
        </tr>
      </table>
    <div class="related">
      <ul>
        <li class="right" >
          <a href="../genindex.html" title="总目录"
             >索引</a></li>
        <li class="right" >
          <a href="model-behaviors.html" title="Model Behaviors"
             >下一页</a> |</li>
        <li class="right" >
          <a href="controllers.html" title="使用控制器（Using Controllers）"
             >上一页</a> |</li> 
      </ul>
    </div>

      <div class="prefooter">
  <div class="container">
      <div class="row">
          <div class="col-sm-3 text-right">
              <span>Follow along:</span>
          </div>
          <div class="col-sm-6 text-center">
              <a href="https://twitter.com/phalconphp" alt="Twitter" class="btn-social btn-social-twitter"><i class="icon-twitter"></i></a>
              <a href="https://www.facebook.com/pages/Phalcon-Framework/134230726685897" alt="Facebook" class="btn-social btn-social-facebook"><i class="icon-facebook"></i></a>
              <a href="https://plus.google.com/102376109340560896457" alt="Google+" class="btn-social btn-social-googleplus"><i class="icon-googleplus"></i></a>
              <a href="https://github.com/phalcon/cphalcon" alt="Github" class="btn-social btn-social-github"><i class="icon-github"></i></a>
          </div>
          <div class="col-sm-3">
          </div>
      </div>
  </div>

</div>
<footer class="footer">
    <div class="container">
        <div class="row">
            <div class="col-xs-4 col-sm-3">
                <h4>Download</h4>
                <ul>
                    <li><a href="/download">Installing Phalcon PHP</a></li>
                    <li><a href="http://docs.phalconphp.com/en/latest/index.html" class="header-nav-link" target="_blank">Documentation</a></li>
                    <li><a href="http://api.phalconphp.com">API</a></li>
                    <li><a href="http://docs.phalconphp.com/en/latest/reference/tutorial.html">Tutorial</a></li>
                    <li><a href="http://docs.phalconphp.com/en/latest/reference/tutorial.html#sample-applications">Sample Applications</a></li>
                </ul>
            </div>
            <div class="col-xs-4 col-sm-3">
                <h4>Community</h4>
                <ul>
                    <li><a href="http://forum.phalconphp.com/" class="header-nav-link" target="_blank">Forum</a></li>
                    <li><a href="https://github.com/phalcon/cphalcon">GitHub</a></li>
                    <li><a href="https://github.com/phalcon/cphalcon/issues">Issue Tracker</a></li>
                    <li><a href="http://stackoverflow.com/questions/tagged/phalcon">Stack Overflow</a></li>
                    <li><a href="/en/testimonials">Testimonials</a></li>
                    <li><a href="http://builtwith.phalconphp.com/">Built with Phalcon</a></li>
                    <li><a href="http://store.phalconphp.com/">Store</a></li>
                </ul>
            </div>
            <div class="col-xs-4 col-sm-2">
                <h4>About</h4>
                <ul>
                    <li><a class="link-black" href="http://blog.phalconphp.com/">Blog</a></li>
                    <li><a href="/en/about">About</a></li>
                    <li><a href="/en/team">Team</a></li>
                    <li><a href="/en/roadmap">Roadmap</a></li>
                    <li><a href="/en/donate">Donate</a></li>
                    <li><a href="/en/consulting">Consulting</a></li>
                    <li><a href="/en/hosting">Hosting</a></li>
                </ul>
            </div>
            <div id="license-spaccer" class="visible-xs"></div>
            <div id="license-wrapper" class="col-xs-12 col-sm-4">
                <p class="license">
                    Phalcon is an open-source PHP framework <br>built as a C-extension. It is available under the <br>
                    <a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank">new BSD License</a>.
                    <br>
                    <br>
                    Except where otherwise noted, content on this site is licensed under the
                    <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 License.</a>
                </p>
            </div>
        </div>
    </div>
</footer>

    </div>
    <script type="text/javascript">
    $(window).on("load", function(){
      var cx = '009733439235723428699:lh9ltjgvdz8';
      var gcse = document.createElement('script');
      gcse.type = 'text/javascript';
      gcse.async = true;
      gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//www.google.com/cse/cse.js?cx=' + cx;
      var s = document.getElementsByTagName('script')[0];
      s.parentNode.insertBefore(gcse, s);
    });
    </script>

  </body>
</html>